diff --git a/dist/bundles/can/test/test.css b/dist/bundles/can/test/test.css new file mode 100644 index 00000000000..e413067be51 --- /dev/null +++ b/dist/bundles/can/test/test.css @@ -0,0 +1,306 @@ +/*qunitjs@1.23.1#qunit/qunit.css!steal-css@1.3.2#css*/ +/*! + * QUnit 1.23.1 + * https://qunitjs.com/ + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license + * https://jquery.org/license + * + * Date: 2016-04-12T17:29Z + */ + +/** Font Family and Sizes */ + +#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-filteredTest, #qunit-userAgent, #qunit-testresult { + font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif; +} + +#qunit-testrunner-toolbar, #qunit-filteredTest, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; } +#qunit-tests { font-size: smaller; } + + +/** Resets */ + +#qunit-tests, #qunit-header, #qunit-banner, #qunit-filteredTest, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter { + margin: 0; + padding: 0; +} + + +/** Header */ + +#qunit-header { + padding: 0.5em 0 0.5em 1em; + + color: #8699A4; + background-color: #0D3349; + + font-size: 1.5em; + line-height: 1em; + font-weight: 400; + + border-radius: 5px 5px 0 0; +} + +#qunit-header a { + text-decoration: none; + color: #C2CCD1; +} + +#qunit-header a:hover, +#qunit-header a:focus { + color: #FFF; +} + +#qunit-testrunner-toolbar label { + display: inline-block; + padding: 0 0.5em 0 0.1em; +} + +#qunit-banner { + height: 5px; +} + +#qunit-testrunner-toolbar { + padding: 0.5em 1em 0.5em 1em; + color: #5E740B; + background-color: #EEE; + overflow: hidden; +} + +#qunit-filteredTest { + padding: 0.5em 1em 0.5em 1em; + background-color: #F4FF77; + color: #366097; +} + +#qunit-userAgent { + padding: 0.5em 1em 0.5em 1em; + background-color: #2B81AF; + color: #FFF; + text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px; +} + +#qunit-modulefilter-container { + float: right; + padding: 0.2em; +} + +.qunit-url-config { + display: inline-block; + padding: 0.1em; +} + +.qunit-filter { + display: block; + float: right; + margin-left: 1em; +} + +/** Tests: Pass/Fail */ + +#qunit-tests { + list-style-position: inside; +} + +#qunit-tests li { + padding: 0.4em 1em 0.4em 1em; + border-bottom: 1px solid #FFF; + list-style-position: inside; +} + +#qunit-tests > li { + display: none; +} + +#qunit-tests li.running, +#qunit-tests li.pass, +#qunit-tests li.fail, +#qunit-tests li.skipped { + display: list-item; +} + +#qunit-tests.hidepass { + position: relative; +} + +#qunit-tests.hidepass li.running, +#qunit-tests.hidepass li.pass { + visibility: hidden; + position: absolute; + width: 0; + height: 0; + padding: 0; + border: 0; + margin: 0; +} + +#qunit-tests li strong { + cursor: pointer; +} + +#qunit-tests li.skipped strong { + cursor: default; +} + +#qunit-tests li a { + padding: 0.5em; + color: #C2CCD1; + text-decoration: none; +} + +#qunit-tests li p a { + padding: 0.25em; + color: #6B6464; +} +#qunit-tests li a:hover, +#qunit-tests li a:focus { + color: #000; +} + +#qunit-tests li .runtime { + float: right; + font-size: smaller; +} + +.qunit-assert-list { + margin-top: 0.5em; + padding: 0.5em; + + background-color: #FFF; + + border-radius: 5px; +} + +.qunit-source { + margin: 0.6em 0 0.3em; +} + +.qunit-collapsed { + display: none; +} + +#qunit-tests table { + border-collapse: collapse; + margin-top: 0.2em; +} + +#qunit-tests th { + text-align: right; + vertical-align: top; + padding: 0 0.5em 0 0; +} + +#qunit-tests td { + vertical-align: top; +} + +#qunit-tests pre { + margin: 0; + white-space: pre-wrap; + word-wrap: break-word; +} + +#qunit-tests del { + background-color: #E0F2BE; + color: #374E0C; + text-decoration: none; +} + +#qunit-tests ins { + background-color: #FFCACA; + color: #500; + text-decoration: none; +} + +/*** Test Counts */ + +#qunit-tests b.counts { color: #000; } +#qunit-tests b.passed { color: #5E740B; } +#qunit-tests b.failed { color: #710909; } + +#qunit-tests li li { + padding: 5px; + background-color: #FFF; + border-bottom: none; + list-style-position: inside; +} + +/*** Passing Styles */ + +#qunit-tests li li.pass { + color: #3C510C; + background-color: #FFF; + border-left: 10px solid #C6E746; +} + +#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; } +#qunit-tests .pass .test-name { color: #366097; } + +#qunit-tests .pass .test-actual, +#qunit-tests .pass .test-expected { color: #999; } + +#qunit-banner.qunit-pass { background-color: #C6E746; } + +/*** Failing Styles */ + +#qunit-tests li li.fail { + color: #710909; + background-color: #FFF; + border-left: 10px solid #EE5757; + white-space: pre; +} + +#qunit-tests > li:last-child { + border-radius: 0 0 5px 5px; +} + +#qunit-tests .fail { color: #000; background-color: #EE5757; } +#qunit-tests .fail .test-name, +#qunit-tests .fail .module-name { color: #000; } + +#qunit-tests .fail .test-actual { color: #EE5757; } +#qunit-tests .fail .test-expected { color: #008000; } + +#qunit-banner.qunit-fail { background-color: #EE5757; } + +/*** Skipped tests */ + +#qunit-tests .skipped { + background-color: #EBECE9; +} + +#qunit-tests .qunit-skipped-label { + background-color: #F4FF77; + display: inline-block; + font-style: normal; + color: #366097; + line-height: 1.8em; + padding: 0 0.5em; + margin: -0.4em 0.4em -0.4em 0; +} + +/** Result */ + +#qunit-testresult { + padding: 0.5em 1em 0.5em 1em; + + color: #2B81AF; + background-color: #D2E0E6; + + border-bottom: 1px solid #FFF; +} +#qunit-testresult .module-name { + font-weight: 700; +} + +/** Fixture */ + +#qunit-fixture { + position: absolute; + top: -10000px; + left: -10000px; + width: 1000px; + height: 1000px; +} diff --git a/dist/bundles/can/test/test.js b/dist/bundles/can/test/test.js new file mode 100644 index 00000000000..e89002fd40a --- /dev/null +++ b/dist/bundles/can/test/test.js @@ -0,0 +1,100631 @@ +/*[system-bundles-config]*/ +System.bundles = {"bundles/can/test/test.css!":["qunitjs@1.23.1#qunit/qunit.css!steal-css@1.3.2#css"]}; +/*npm-utils*/ +define('npm-utils', function (require, exports, module) { + (function (global, require, exports, module) { + var slice = Array.prototype.slice; + var npmModuleRegEx = /.+@.+\..+\..+#.+/; + var conditionalModuleRegEx = /#\{[^\}]+\}|#\?.+$/; + var gitUrlEx = /(git|http(s?)):\/\//; + var supportsSet = typeof Set === 'function'; + var utils = { + extend: function (d, s, deep, existingSet) { + var val; + var set = existingSet; + if (deep) { + if (!set) { + if (supportsSet) { + set = new Set(); + } else { + set = []; + } + } + if (supportsSet) { + if (set.has(s)) { + return s; + } else { + set.add(s); + } + } else { + if (set.indexOf(s) !== -1) { + return s; + } else { + set.push(s); + } + } + } + for (var prop in s) { + val = s[prop]; + if (deep) { + if (utils.isArray(val)) { + d[prop] = slice.call(val); + } else if (utils.isPlainObject(val)) { + d[prop] = utils.extend({}, val, deep, set); + } else { + d[prop] = s[prop]; + } + } else { + d[prop] = s[prop]; + } + } + return d; + }, + map: function (arr, fn) { + var i = 0, len = arr.length, out = []; + for (; i < len; i++) { + out.push(fn.call(arr, arr[i])); + } + return out; + }, + filter: function (arr, fn) { + var i = 0, len = arr.length, out = [], res; + for (; i < len; i++) { + res = fn.call(arr, arr[i]); + if (res) { + out.push(arr[i]); + } + } + return out; + }, + forEach: function (arr, fn) { + var i = 0, len = arr.length; + for (; i < len; i++) { + fn.call(arr, arr[i], i); + } + }, + flow: function (fns) { + return function () { + var res = fns[0].apply(this, arguments); + for (var i = 1; i < fns.length; i++) { + res = fns[i].call(this, res); + } + return res; + }; + }, + isObject: function (obj) { + return typeof obj === 'object'; + }, + isPlainObject: function (obj) { + return utils.isObject(obj) && (!obj || obj.__proto__ === Object.prototype); + }, + isArray: Array.isArray || function (arr) { + return Object.prototype.toString.call(arr) === '[object Array]'; + }, + isEnv: function (name) { + return this.isEnv ? this.isEnv(name) : this.env === name; + }, + isGitUrl: function (str) { + return gitUrlEx.test(str); + }, + warnOnce: function (msg) { + var w = this._warnings = this._warnings || {}; + if (w[msg]) + return; + w[msg] = true; + this.warn(msg); + }, + warn: function (msg) { + if (typeof steal !== 'undefined' && typeof console !== 'undefined' && console.warn) { + steal.done().then(function () { + if (steal.dev && steal.dev.warn) { + } else if (console.warn) { + console.warn('steal.js WARNING: ' + msg); + } else { + console.log(msg); + } + }); + } + }, + relativeURI: function (baseURL, url) { + return typeof steal !== 'undefined' ? steal.relativeURI(baseURL, url) : url; + }, + moduleName: { + create: function (descriptor, standard) { + if (standard) { + return descriptor.moduleName; + } else { + if (descriptor === '@empty') { + return descriptor; + } + var modulePath; + if (descriptor.modulePath) { + modulePath = descriptor.modulePath.substr(0, 2) === './' ? descriptor.modulePath.substr(2) : descriptor.modulePath; + } + var version = descriptor.version; + if (version && version[0] !== '^') { + version = encodeURIComponent(decodeURIComponent(version)); + } + return descriptor.packageName + (version ? '@' + version : '') + (modulePath ? '#' + modulePath : '') + (descriptor.plugin ? descriptor.plugin : ''); + } + }, + isNpm: function (moduleName) { + return npmModuleRegEx.test(moduleName); + }, + isConditional: function (moduleName) { + return conditionalModuleRegEx.test(moduleName); + }, + isFullyConvertedNpm: function (parsedModuleName) { + return !!(parsedModuleName.packageName && parsedModuleName.version && parsedModuleName.modulePath); + }, + isScoped: function (moduleName) { + return moduleName[0] === '@'; + }, + parse: function (moduleName, currentPackageName, global, context) { + var pluginParts = moduleName.split('!'); + var modulePathParts = pluginParts[0].split('#'); + var versionParts = modulePathParts[0].split('@'); + if (!modulePathParts[1] && !versionParts[0]) { + versionParts = ['@' + versionParts[1]]; + } + if (versionParts.length === 3 && utils.moduleName.isScoped(moduleName)) { + versionParts.splice(0, 1); + versionParts[0] = '@' + versionParts[0]; + } + var packageName, modulePath; + if (currentPackageName && utils.path.isRelative(moduleName)) { + packageName = currentPackageName; + modulePath = versionParts[0]; + } else if (currentPackageName && utils.path.isInHomeDir(moduleName, context)) { + packageName = currentPackageName; + modulePath = versionParts[0].split('/').slice(1).join('/'); + } else { + if (modulePathParts[1]) { + packageName = versionParts[0]; + modulePath = modulePathParts[1]; + } else { + var folderParts = versionParts[0].split('/'); + if (folderParts.length && folderParts[0][0] === '@') { + packageName = folderParts.splice(0, 2).join('/'); + } else { + packageName = folderParts.shift(); + } + modulePath = folderParts.join('/'); + } + } + modulePath = utils.path.removeJS(modulePath); + return { + plugin: pluginParts.length === 2 ? '!' + pluginParts[1] : undefined, + version: versionParts[1], + modulePath: modulePath, + packageName: packageName, + moduleName: moduleName, + isGlobal: global + }; + }, + parseFromPackage: function (loader, refPkg, name, parentName) { + var packageName = utils.pkg.name(refPkg), parsedModuleName = utils.moduleName.parse(name, packageName, undefined, { loader: loader }), isRelative = utils.path.isRelative(parsedModuleName.modulePath); + if (isRelative && !parentName) { + throw new Error('Cannot resolve a relative module identifier ' + 'with no parent module:', name); + } + if (isRelative) { + var parentParsed = utils.moduleName.parse(parentName, packageName); + if (parentParsed.packageName === parsedModuleName.packageName && parentParsed.modulePath) { + var makePathRelative = true; + if (name === '../' || name === './' || name === '..') { + var relativePath = utils.path.relativeTo(parentParsed.modulePath, name); + var isInRoot = utils.path.isPackageRootDir(relativePath); + if (isInRoot) { + parsedModuleName.modulePath = utils.pkg.main(refPkg); + makePathRelative = false; + } else { + parsedModuleName.modulePath = name + (utils.path.endsWithSlash(name) ? '' : '/') + 'index'; + } + } + if (makePathRelative) { + parsedModuleName.modulePath = utils.path.makeRelative(utils.path.joinURIs(parentParsed.modulePath, parsedModuleName.modulePath)); + } + } + } + var mapName = utils.moduleName.create(parsedModuleName), refSteal = utils.pkg.config(refPkg), mappedName; + if (refPkg.browser && typeof refPkg.browser !== 'string' && mapName in refPkg.browser && (!refSteal || !refSteal.ignoreBrowser)) { + mappedName = refPkg.browser[mapName] === false ? '@empty' : refPkg.browser[mapName]; + } + var global = loader && loader.globalBrowser && loader.globalBrowser[mapName]; + if (global) { + mappedName = global.moduleName === false ? '@empty' : global.moduleName; + } + if (mappedName) { + return utils.moduleName.parse(mappedName, packageName, !!global); + } else { + return parsedModuleName; + } + }, + nameAndVersion: function (parsedModuleName) { + return parsedModuleName.packageName + '@' + parsedModuleName.version; + }, + isBareIdentifier: function (identifier) { + return identifier && identifier[0] !== '.' && identifier[0] !== '@'; + } + }, + pkg: { + name: function (pkg) { + var steal = utils.pkg.config(pkg); + return steal && steal.name || pkg.name; + }, + main: function (pkg) { + var main; + var steal = utils.pkg.config(pkg); + if (steal && steal.main) { + main = steal.main; + } else if (typeof pkg.browser === 'string') { + if (utils.path.endsWithSlash(pkg.browser)) { + main = pkg.browser + 'index'; + } else { + main = pkg.browser; + } + } else if (typeof pkg.jam === 'object' && pkg.jam.main) { + main = pkg.jam.main; + } else if (pkg.main) { + main = pkg.main; + } else { + main = 'index'; + } + return utils.path.removeJS(utils.path.removeDotSlash(main)); + }, + rootDir: function (pkg, isRoot) { + var root = isRoot ? utils.path.removePackage(pkg.fileUrl) : utils.path.pkgDir(pkg.fileUrl); + var lib = utils.pkg.directoriesLib(pkg); + if (lib) { + root = utils.path.joinURIs(utils.path.addEndingSlash(root), lib); + } + return root; + }, + isRoot: function (loader, pkg) { + var root = utils.pkg.getDefault(loader); + return pkg && pkg.name === root.name && pkg.version === root.version; + }, + homeAlias: function (context) { + return context && context.loader && context.loader.homeAlias || '~'; + }, + getDefault: function (loader) { + return loader.npmPaths.__default; + }, + findByModuleNameOrAddress: function (loader, moduleName, moduleAddress) { + if (loader.npm) { + if (moduleName) { + var parsed = utils.moduleName.parse(moduleName); + if (parsed.version && parsed.packageName) { + var name = parsed.packageName + '@' + parsed.version; + if (name in loader.npm) { + return loader.npm[name]; + } + } + } + if (moduleAddress) { + var startingAddress = utils.relativeURI(loader.baseURL, moduleAddress); + var packageFolder = utils.pkg.folderAddress(startingAddress); + return packageFolder ? loader.npmPaths[packageFolder] : utils.pkg.getDefault(loader); + } else { + return utils.pkg.getDefault(loader); + } + } + }, + folderAddress: function (address) { + var nodeModules = '/node_modules/', nodeModulesIndex = address.lastIndexOf(nodeModules), nextSlash = address.indexOf('/', nodeModulesIndex + nodeModules.length); + if (nodeModulesIndex >= 0) { + return nextSlash >= 0 ? address.substr(0, nextSlash) : address; + } + }, + findDep: function (loader, refPkg, name) { + if (loader.npm && refPkg && !utils.path.startsWithDotSlash(name)) { + var nameAndVersion = name + '@' + refPkg.resolutions[name]; + var pkg = loader.npm[nameAndVersion]; + return pkg; + } + }, + findDepWalking: function (loader, refPackage, name) { + if (loader.npm && refPackage && !utils.path.startsWithDotSlash(name)) { + var curPackage = utils.path.depPackageDir(refPackage.fileUrl, name); + while (curPackage) { + var pkg = loader.npmPaths[curPackage]; + if (pkg) { + return pkg; + } + var parentAddress = utils.path.parentNodeModuleAddress(curPackage); + if (!parentAddress) { + return; + } + curPackage = parentAddress + '/' + name; + } + } + }, + findByName: function (loader, name) { + if (loader.npm && !utils.path.startsWithDotSlash(name)) { + return loader.npm[name]; + } + }, + findByNameAndVersion: function (loader, name, version) { + if (loader.npm && !utils.path.startsWithDotSlash(name)) { + var nameAndVersion = name + '@' + version; + return loader.npm[nameAndVersion]; + } + }, + findByUrl: function (loader, url) { + if (loader.npm) { + var fullUrl = utils.pkg.folderAddress(url); + return loader.npmPaths[fullUrl]; + } + }, + directoriesLib: function (pkg) { + var steal = utils.pkg.config(pkg); + var lib = steal && steal.directories && steal.directories.lib; + var ignores = [ + '.', + '/' + ], ignore; + if (!lib) + return undefined; + while (!!(ignore = ignores.shift())) { + if (lib[0] === ignore) { + lib = lib.substr(1); + } + } + return lib; + }, + hasDirectoriesLib: function (pkg) { + var steal = utils.pkg.config(pkg); + return steal && steal.directories && !!steal.directories.lib; + }, + findPackageInfo: function (context, pkg) { + var pkgInfo = context.pkgInfo; + if (pkgInfo) { + var out; + utils.forEach(pkgInfo, function (p) { + if (pkg.name === p.name && pkg.version === p.version) { + out = p; + } + }); + return out; + } + }, + saveResolution: function (context, refPkg, pkg) { + var npmPkg = utils.pkg.findPackageInfo(context, refPkg); + npmPkg.resolutions[pkg.name] = refPkg.resolutions[pkg.name] = pkg.version; + }, + config: function (pkg) { + return pkg.steal || pkg.system; + } + }, + path: { + makeRelative: function (path) { + if (utils.path.isRelative(path) && path.substr(0, 1) !== '/') { + return path; + } else { + return './' + path; + } + }, + removeJS: function (path) { + return path.replace(/\.js(!|$)/, function (whole, part) { + return part; + }); + }, + removePackage: function (path) { + return path.replace(/\/package\.json.*/, ''); + }, + addJS: function (path) { + if (/\.m?js(on)?$/.test(path)) { + return path; + } else { + return path + '.js'; + } + }, + isRelative: function (path) { + return path.substr(0, 1) === '.'; + }, + isInHomeDir: function (path, context) { + return path.substr(0, 2) === utils.pkg.homeAlias(context) + '/'; + }, + joinURIs: function (baseUri, rel) { + function removeDotSegments(input) { + var output = []; + input.replace(/^(\.\.?(\/|$))+/, '').replace(/\/(\.(\/|$))+/g, '/').replace(/\/\.\.$/, '/../').replace(/\/?[^\/]*/g, function (p) { + if (p === '/..') { + output.pop(); + } else { + output.push(p); + } + }); + return output.join('').replace(/^\//, input.charAt(0) === '/' ? '/' : ''); + } + var href = parseURI(rel || ''); + var base = parseURI(baseUri || ''); + return !href || !base ? null : (href.protocol || base.protocol) + (href.protocol || href.authority ? href.authority : base.authority) + removeDotSegments(href.protocol || href.authority || href.pathname.charAt(0) === '/' ? href.pathname : href.pathname ? (base.authority && !base.pathname ? '/' : '') + base.pathname.slice(0, base.pathname.lastIndexOf('/') + 1) + href.pathname : base.pathname) + (href.protocol || href.authority || href.pathname ? href.search : href.search || base.search) + href.hash; + }, + startsWithDotSlash: function (path) { + return path.substr(0, 2) === './'; + }, + removeDotSlash: function (path) { + return utils.path.startsWithDotSlash(path) ? path.substr(2) : path; + }, + endsWithSlash: function (path) { + return path[path.length - 1] === '/'; + }, + addEndingSlash: function (path) { + return utils.path.endsWithSlash(path) ? path : path + '/'; + }, + depPackage: function (parentPackageAddress, childName) { + var packageFolderName = parentPackageAddress.replace(/\/package\.json.*/, ''); + return (packageFolderName ? packageFolderName + '/' : '') + 'node_modules/' + childName + '/package.json'; + }, + peerPackage: function (parentPackageAddress, childName) { + var packageFolderName = parentPackageAddress.replace(/\/package\.json.*/, ''); + return packageFolderName.substr(0, packageFolderName.lastIndexOf('/')) + '/' + childName + '/package.json'; + }, + depPackageDir: function (parentPackageAddress, childName) { + return utils.path.depPackage(parentPackageAddress, childName).replace(/\/package\.json.*/, ''); + }, + peerNodeModuleAddress: function (address) { + var nodeModules = '/node_modules/', nodeModulesIndex = address.lastIndexOf(nodeModules); + if (nodeModulesIndex >= 0) { + return address.substr(0, nodeModulesIndex + nodeModules.length - 1); + } + }, + parentNodeModuleAddress: function (address) { + var nodeModules = '/node_modules/', nodeModulesIndex = address.lastIndexOf(nodeModules), prevModulesIndex = address.lastIndexOf(nodeModules, nodeModulesIndex - 1); + if (prevModulesIndex >= 0) { + return address.substr(0, prevModulesIndex + nodeModules.length - 1); + } + }, + pkgDir: function (address) { + var nodeModules = '/node_modules/', nodeModulesIndex = address.lastIndexOf(nodeModules), nextSlash = address.indexOf('/', nodeModulesIndex + nodeModules.length); + if (address[nodeModulesIndex + nodeModules.length] === '@') { + nextSlash = address.indexOf('/', nextSlash + 1); + } + if (nodeModulesIndex >= 0) { + return nextSlash >= 0 ? address.substr(0, nextSlash) : address; + } + }, + basename: function (address) { + var parts = address.split('/'); + return parts[parts.length - 1]; + }, + relativeTo: function (modulePath, rel) { + var parts = modulePath.split('/'); + var idx = 1; + while (rel[idx] === '.') { + parts.pop(); + idx++; + } + return parts.join('/'); + }, + isPackageRootDir: function (pth) { + return pth.indexOf('/') === -1; + } + }, + json: { + transform: function (loader, load, data) { + data.steal = utils.pkg.config(data); + var fn = loader.jsonOptions && loader.jsonOptions.transform; + if (!fn) + return data; + return fn.call(loader, load, data); + } + }, + includeInBuild: true + }; + function parseURI(url) { + var m = String(url).replace(/^\s+|\s+$/g, '').match(/^([^:\/?#]+:)?(\/\/(?:[^:@\/]*(?::[^:@\/]*)?@)?(([^:\/?#]*)(?::(\d*))?))?([^?#]*)(\?[^#]*)?(#[\s\S]*)?/); + return m ? { + href: m[0] || '', + protocol: m[1] || '', + authority: m[2] || '', + host: m[3] || '', + hostname: m[4] || '', + port: m[5] || '', + pathname: m[6] || '', + search: m[7] || '', + hash: m[8] || '' + } : null; + } + module.exports = utils; + }(function () { + return this; + }(), require, exports, module)); +}); +/*npm-extension*/ +define('npm-extension', [ + 'require', + 'exports', + 'module', + '@steal', + './npm-utils' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'format cjs'; + var steal = require('@steal'); + var utils = require('./npm-utils'); + exports.includeInBuild = true; + var isNode = typeof process === 'object' && {}.toString.call(process) === '[object process]'; + var isWorker = typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope; + var isElectron = isNode && !!process.versions.electron; + var isBrowser = typeof window !== 'undefined' && (!isNode || isElectron) && !isWorker; + exports.addExtension = function (System) { + if (System._extensions) { + System._extensions.push(exports.addExtension); + } + var oldNormalize = System.normalize; + System.normalize = function (identifier, parentModuleName, parentAddress, pluginNormalize) { + var name = identifier; + var parentName = parentModuleName; + if (parentName && this.npmParentMap && this.npmParentMap[parentName]) { + parentName = this.npmParentMap[parentName]; + } + var hasNoParent = !parentName; + var nameIsRelative = utils.path.isRelative(name); + var parentIsNpmModule = utils.moduleName.isNpm(parentName); + var identifierEndsWithSlash = utils.path.endsWithSlash(name); + if (parentName && nameIsRelative && !parentIsNpmModule) { + return oldNormalize.call(this, name, parentName, parentAddress, pluginNormalize); + } + if (utils.moduleName.isConditional(name)) { + return oldNormalize.call(this, name, parentName, parentAddress, pluginNormalize); + } + var hasContextualMap = typeof this.map[parentName] === 'object' && this.map[parentName][name]; + if (hasContextualMap) { + return oldNormalize.call(this, name, parentName, parentAddress, pluginNormalize); + } + var refPkg = utils.pkg.findByModuleNameOrAddress(this, parentName, parentAddress); + if (!refPkg) { + return oldNormalize.call(this, name, parentName, parentAddress, pluginNormalize); + } + var isPointingAtParentFolder = name === '../' || name === './'; + if (parentIsNpmModule && isPointingAtParentFolder) { + var parsedParentModuleName = utils.moduleName.parse(parentName); + var parentModulePath = parsedParentModuleName.modulePath || ''; + var relativePath = utils.path.relativeTo(parentModulePath, name); + var isInRoot = utils.path.isPackageRootDir(relativePath); + if (isInRoot) { + name = refPkg.name + '#' + utils.path.removeJS(utils.path.removeDotSlash(refPkg.main)); + } else { + name = name + 'index'; + } + } + var parsedModuleName = utils.moduleName.parseFromPackage(this, refPkg, name, parentName); + var isRoot = utils.pkg.isRoot(this, refPkg); + var parsedPackageNameIsReferringPackage = parsedModuleName.packageName === refPkg.name; + var isRelativeToParentNpmModule = parentIsNpmModule && nameIsRelative && parsedPackageNameIsReferringPackage; + var depPkg, wantedPkg; + if (isRelativeToParentNpmModule) { + depPkg = refPkg; + } + var context = this.npmContext; + var crawl = context && context.crawl; + var isDev = !!crawl; + if (!depPkg) { + if (crawl) { + var parentPkg = nameIsRelative ? null : crawl.matchedVersion(context, refPkg.name, refPkg.version); + if (parentPkg) { + var depMap = crawl.getFullDependencyMap(this, parentPkg, isRoot); + wantedPkg = depMap[parsedModuleName.packageName]; + if (wantedPkg) { + var wantedVersion = refPkg.resolutions && refPkg.resolutions[wantedPkg.name] || wantedPkg.version; + var foundPkg = crawl.matchedVersion(this.npmContext, wantedPkg.name, wantedVersion); + if (foundPkg) { + depPkg = utils.pkg.findByUrl(this, foundPkg.fileUrl); + } + } + } + } else { + if (isRoot) { + depPkg = utils.pkg.findDepWalking(this, refPkg, parsedModuleName.packageName); + } else { + depPkg = utils.pkg.findDep(this, refPkg, parsedModuleName.packageName); + } + } + } + if (parsedPackageNameIsReferringPackage) { + depPkg = utils.pkg.findByNameAndVersion(this, parsedModuleName.packageName, refPkg.version); + } + var lookupByName = parsedModuleName.isGlobal || hasNoParent; + if (!depPkg) { + depPkg = utils.pkg.findByName(this, parsedModuleName.packageName); + } + var isThePackageWeWant = !isDev || !depPkg || (wantedPkg ? crawl.pkgSatisfies(depPkg, wantedPkg.version) : true); + if (!isThePackageWeWant) { + depPkg = undefined; + } else if (isDev && depPkg) { + utils.pkg.saveResolution(context, refPkg, depPkg); + } + if (!depPkg) { + var browserPackageName = this.globalBrowser[parsedModuleName.packageName]; + if (browserPackageName) { + parsedModuleName.packageName = browserPackageName.moduleName; + depPkg = utils.pkg.findByName(this, parsedModuleName.packageName); + } + } + if (!depPkg && isRoot && name === refPkg.main && utils.pkg.hasDirectoriesLib(refPkg)) { + parsedModuleName.version = refPkg.version; + parsedModuleName.packageName = refPkg.name; + parsedModuleName.modulePath = utils.pkg.main(refPkg); + return oldNormalize.call(this, utils.moduleName.create(parsedModuleName), parentName, parentAddress, pluginNormalize); + } + var loader = this; + if (!depPkg) { + if (crawl) { + var parentPkg = crawl.matchedVersion(this.npmContext, refPkg.name, refPkg.version); + if (parentPkg) { + var depMap = crawl.getFullDependencyMap(this, parentPkg, isRoot); + depPkg = depMap[parsedModuleName.packageName]; + if (!depPkg) { + var parents = crawl.findPackageAndParents(this.npmContext, parsedModuleName.packageName); + if (parents) { + depPkg = parents.package; + } + } + } + } + if (!depPkg) { + if (refPkg.browser && refPkg.browser[name]) { + return oldNormalize.call(this, refPkg.browser[name], parentName, parentAddress, pluginNormalize); + } + var steal = utils.pkg.config(refPkg); + if (steal && steal.map && typeof steal.map[name] === 'string') { + var mappedName = steal.map[name]; + var envConfig = steal.envs && steal.envs[loader.env]; + if (envConfig && envConfig.map && typeof envConfig.map[name] === 'string') { + mappedName = envConfig.map[name]; + } + return loader.normalize(mappedName, parentName, parentAddress, pluginNormalize); + } else { + return oldNormalize.call(this, name, parentName, parentAddress, pluginNormalize); + } + } + return crawl.dep(this.npmContext, parentPkg, refPkg, depPkg, isRoot).then(createModuleNameAndNormalize); + } else { + return createModuleNameAndNormalize(depPkg); + } + function createModuleNameAndNormalize(depPkg) { + parsedModuleName.version = depPkg.version; + if (!parsedModuleName.modulePath) { + parsedModuleName.modulePath = utils.pkg.main(depPkg); + } + var p = oldNormalize.call(loader, utils.moduleName.create(parsedModuleName), parentName, parentAddress, pluginNormalize); + if (identifierEndsWithSlash) { + p.then(function (name) { + if (context && context.forwardSlashMap) { + context.forwardSlashMap[name] = true; + } + }); + } + return p; + } + }; + var oldLocate = System.locate; + System.locate = function (load) { + var parsedModuleName = utils.moduleName.parse(load.name), loader = this; + var pmn = load.metadata.parsedModuleName = parsedModuleName; + load.metadata.npmPackage = utils.pkg.findByNameAndVersion(this, pmn.packageName, pmn.version); + if (parsedModuleName.version && this.npm && !loader.paths[load.name]) { + var pkg = this.npm[utils.moduleName.nameAndVersion(parsedModuleName)]; + if (pkg) { + return oldLocate.call(this, load).then(function (locatedAddress) { + var address = locatedAddress; + var expectedAddress = utils.path.joinURIs(System.baseURL, load.name); + if (isBrowser) { + expectedAddress = expectedAddress.replace(/#/g, '%23'); + } + if (address !== expectedAddress + '.js' && address !== expectedAddress) { + return address; + } + var root = utils.pkg.rootDir(pkg, utils.pkg.isRoot(loader, pkg)); + if (parsedModuleName.modulePath) { + var npmAddress = utils.path.joinURIs(utils.path.addEndingSlash(root), parsedModuleName.plugin ? parsedModuleName.modulePath : utils.path.addJS(parsedModuleName.modulePath)); + address = typeof steal !== 'undefined' ? utils.path.joinURIs(loader.baseURL, npmAddress) : npmAddress; + } + return address; + }); + } + } + return oldLocate.call(this, load); + }; + var oldFetch = System.fetch; + System.fetch = function (load) { + if (load.metadata.dryRun) { + return oldFetch.apply(this, arguments); + } + var loader = this; + var context = loader.npmContext; + var fetchPromise = Promise.resolve(oldFetch.apply(this, arguments)); + if (utils.moduleName.isNpm(load.name)) { + fetchPromise = fetchPromise.then(null, function (err) { + var statusCode = err.statusCode; + if (statusCode !== 404 && statusCode !== 0) { + return Promise.reject(err); + } + if (!loader.npmContext) { + loader.npmContext = { forwardSlashMap: {} }; + } + var types = [].slice.call(retryTypes); + return retryAll(types, err).then(null, function (e) { + return Promise.reject(err); + }); + function retryAll(types, err) { + if (!types.length) { + throw err; + } + var type = types.shift(); + if (!type.test(load)) { + throw err; + } + return Promise.resolve(retryFetch.call(loader, load, type)).then(null, function (err) { + return retryAll(types, err); + }); + } + }); + } + return fetchPromise.catch(function (error) { + var statusCode = error.statusCode; + if ((statusCode === 404 || statusCode === 0) && utils.moduleName.isBareIdentifier(load.name) && !utils.pkg.isRoot(loader, load.metadata.npmPackage)) { + var newError = new Error([ + 'Could not load \'' + load.name + '\'', + 'Is this an npm module not saved in your package.json?' + ].join('\n')); + newError.statusCode = error.statusCode; + throw newError; + } else { + throw error; + } + }); + }; + var convertName = function (loader, name) { + var pkg = utils.pkg.findByName(loader, name.split('/')[0]); + if (pkg) { + var parsed = utils.moduleName.parse(name, pkg.name); + parsed.version = pkg.version; + if (!parsed.modulePath) { + parsed.modulePath = utils.pkg.main(pkg); + } + return utils.moduleName.create(parsed); + } + return name; + }; + var configSpecial = { + map: function (map) { + var newMap = {}, val; + for (var name in map) { + val = map[name]; + newMap[convertName(this, name)] = typeof val === 'object' ? configSpecial.map(val) : convertName(this, val); + } + return newMap; + }, + meta: function (map) { + var newMap = {}; + for (var name in map) { + newMap[convertName(this, name)] = map[name]; + } + return newMap; + }, + paths: function (paths) { + var newPaths = {}; + for (var name in paths) { + newPaths[convertName(this, name)] = paths[name]; + } + return newPaths; + } + }; + var oldConfig = System.config; + System.config = function (cfg) { + var loader = this; + if (loader.npmContext) { + var context = loader.npmContext; + var pkg = context.versions.__default; + var conv = context.convert.steal(context, pkg, cfg, true); + context.convert.updateConfigOnPackageLoad(conv, false, true, context.applyBuildConfig); + oldConfig.apply(loader, arguments); + return; + } + for (var name in cfg) { + if (configSpecial[name]) { + cfg[name] = configSpecial[name].call(loader, cfg[name]); + } + } + oldConfig.apply(loader, arguments); + }; + var newLoader = System._newLoader || Function.prototype; + System._newLoader = function (loader) { + loader.npmContext = this.npmContext; + loader.npmParentMap = this.npmParentMap; + return newLoader.apply(this, arguments); + }; + steal.addNpmPackages = function (npmPackages) { + var packages = npmPackages || []; + var loader = this.loader; + for (var i = 0; i < packages.length; i += 1) { + var pkg = packages[i]; + var path = pkg && pkg.fileUrl; + if (path) { + loader.npmContext.paths[path] = pkg; + } + } + }; + steal.getNpmPackages = function () { + var context = this.loader.npmContext; + return context ? context.packages || [] : []; + }; + function retryFetch(load, type) { + var loader = this; + var moduleName = typeof type.name === 'function' ? type.name(loader, load) : load.name + type.name; + var local = utils.extend({}, load); + local.name = moduleName; + local.metadata = { dryRun: true }; + return Promise.resolve(loader.locate(local)).then(function (address) { + local.address = address; + return loader.fetch(local); + }).then(function (source) { + load.metadata.address = local.address; + loader.npmParentMap[load.name] = local.name; + var npmLoad = loader.npmContext && loader.npmContext.npmLoad; + if (npmLoad) { + npmLoad.saveLoadIfNeeded(loader.npmContext); + if (!isNode) { + utils.warnOnce('Some 404s were encountered ' + 'while loading. Don\'t panic! ' + 'These will only happen in dev ' + 'and are harmless.'); + } + } + return source; + }); + } + var retryTypes = [ + { + name: function (loader, load) { + var context = loader.npmContext; + if (context.forwardSlashMap[load.name]) { + var parts = load.name.split('/'); + parts.pop(); + return parts.concat(['index']).join('/'); + } + return load.name + '/index'; + }, + test: function () { + return true; + } + }, + { + name: '.json', + test: function (load) { + return utils.moduleName.isNpm(load.name) && utils.path.basename(load.address) === 'package.js'; + } + } + ]; + }; + }(function () { + return this; + }(), require, exports, module)); +}); +/*node_modules/steal-conditional/conditional*/ +define('node_modules/steal-conditional/conditional', [ + 'module', + 'exports' +], function (module, exports) { + exports.extensionBuilder = 'steal-conditional/slim'; + function addConditionals(loader) { + var conditionalRegEx = /#\{[^\}]+\}|#\?.+$/; + var isNode = typeof process === 'object' && {}.toString.call(process) === '[object process]'; + if (loader._extensions) { + loader._extensions.push(addConditionals); + } + loader.set('@@conditional-helpers', loader.newModule({ + isConditionalModuleName: function (moduleName) { + return conditionalRegEx.test(moduleName); + } + })); + var normalize = loader.normalize; + function readMemberExpression(p, value) { + var pParts = p.split('.'); + while (pParts.length) { + value = value[pParts.shift()]; + } + return value; + } + function includeInBuild(loader, name) { + var load = loader.getModuleLoad(name); + load.metadata.includeInBuild = true; + } + function getGlob() { + if (isNode) { + return loader.import('@node-require', { name: module.id }).then(function (nodeRequire) { + return nodeRequire('glob'); + }); + } + return Promise.resolve(); + } + function pushIfUnique(array, item) { + return array.indexOf(item) === -1 ? array.push(item) : array.length; + } + function getModuleName(nameWithConditional, variation) { + var modName; + var conditionIndex = nameWithConditional.search(conditionalRegEx); + var lastSlashIndex = nameWithConditional.indexOf('/', nameWithConditional.indexOf('}')); + if (lastSlashIndex !== -1) { + modName = nameWithConditional.substr(0, conditionIndex) + variation; + } else { + modName = nameWithConditional.replace(conditionalRegEx, variation); + } + return modName; + } + loader.normalize = function (name, parentName, parentAddress, pluginNormalize) { + var loader = this; + var conditionalMatch = name.match(conditionalRegEx); + if (conditionalMatch) { + var substitution = conditionalMatch[0][1] !== '?'; + var conditionModule = substitution ? conditionalMatch[0].substr(2, conditionalMatch[0].length - 3) : conditionalMatch[0].substr(2); + var conditionExport = 'default'; + var conditionExportParts = conditionModule.match(/^(?:\.\/|\.\.\/)+/); + var conditionExportIndex = conditionModule.indexOf('.', conditionExportParts && conditionExportParts[0].length); + if (conditionExportIndex !== -1) { + conditionExport = conditionModule.substr(conditionExportIndex + 1); + conditionModule = conditionModule.substr(0, conditionExportIndex); + } + var booleanNegation = !substitution && conditionModule[0] === '~'; + if (booleanNegation) { + conditionModule = conditionModule.substr(1); + } + var handleConditionalBuild = function () { + }; + var handleConditionalEval = function (m) { + var conditionValue = typeof m === 'object' ? readMemberExpression(conditionExport, m) : m; + if (substitution) { + if (typeof conditionValue !== 'string') { + throw new TypeError('The condition value for ' + conditionalMatch[0] + ' doesn\'t resolve to a string.'); + } + name = name.replace(conditionalRegEx, conditionValue); + } else { + if (typeof conditionValue !== 'boolean') { + throw new TypeError('The condition value for ' + conditionalMatch[0] + ' isn\'t resolving to a boolean.'); + } + if (booleanNegation) { + conditionValue = !conditionValue; + } + if (!conditionValue) { + name = '@empty'; + } else { + name = name.replace(conditionalRegEx, ''); + } + } + if (name === '@empty') { + return normalize.call(loader, name, parentName, parentAddress, pluginNormalize); + } else { + return loader.normalize.call(loader, name, parentName, parentAddress, pluginNormalize); + } + }; + var isBuild = (loader.env || '').indexOf('build') === 0; + var pluginLoader = isBuild ? loader : loader.pluginLoader || loader; + return pluginLoader['import'](conditionModule, { + name: parentName, + address: parentAddress + }).then(function (m) { + return pluginLoader.normalize(conditionModule, parentName, parentAddress, pluginNormalize).then(function (fullName) { + includeInBuild(pluginLoader, fullName); + return m; + }); + }).then(function (m) { + return isBuild ? handleConditionalBuild() : handleConditionalEval(m); + }); + } + return Promise.resolve(normalize.call(loader, name, parentName, parentAddress, pluginNormalize)); + }; + } + if (typeof System !== 'undefined') { + addConditionals(System); + } +}); +/*npm-load*/ +define('npm-load', [], function(){ return {}; }); +/*semver*/ +define('semver', [], function(){ return {}; }); +/*npm-crawl*/ +define('npm-crawl', [], function(){ return {}; }); +/*npm-convert*/ +define('npm-convert', [], function(){ return {}; }); +/*npm*/ +define('npm', [], function(){ return {}; }); +/*package.json!npm*/ +define('package.json!npm', [ + '@loader', + 'npm-extension', + 'module', + './node_modules/steal-conditional/conditional.js', + './node_modules/steal-conditional/conditional.js' +], function (loader, npmExtension, module) { + npmExtension.addExtension(loader); + if (!loader.main) { + loader.main = 'can@5.17.1#can'; + } + loader._npmExtensions = [].slice.call(arguments, 2); + (function (loader, packages, options) { + var g = loader.global; + if (!g.process) { + g.process = { + argv: [], + cwd: function () { + var baseURL = loader.baseURL; + return baseURL; + }, + browser: true, + env: { NODE_ENV: loader.env }, + version: '', + platform: navigator && navigator.userAgent && /Windows/.test(navigator.userAgent) ? 'win' : '' + }; + } + if (!loader.npm) { + loader.npm = {}; + loader.npmPaths = {}; + loader.globalBrowser = {}; + } + if (!loader.npmParentMap) { + loader.npmParentMap = options.npmParentMap || {}; + } + var rootPkg = loader.npmPaths.__default = packages[0]; + var rootConfig = rootPkg.steal || rootPkg.system; + var lib = rootConfig && rootConfig.directories && rootConfig.directories.lib; + var setGlobalBrowser = function (globals, pkg) { + for (var name in globals) { + loader.globalBrowser[name] = { + pkg: pkg, + moduleName: globals[name] + }; + } + }; + var setInNpm = function (name, pkg) { + if (!loader.npm[name]) { + loader.npm[name] = pkg; + } + loader.npm[name + '@' + pkg.version] = pkg; + }; + var forEach = function (arr, fn) { + var i = 0, len = arr.length; + for (; i < len; i++) { + res = fn.call(arr, arr[i], i); + if (res === false) + break; + } + }; + var setupLiveReload = function () { + if (loader.liveReloadInstalled) { + loader['import']('live-reload', { name: module.id }).then(function (reload) { + reload.dispose(function () { + var pkgInfo = loader.npmContext.pkgInfo; + delete pkgInfo[rootPkg.name + '@' + rootPkg.version]; + var idx = -1; + forEach(pkgInfo, function (pkg, i) { + if (pkg.name === rootPkg.name && pkg.version === rootPkg.version) { + idx = i; + return false; + } + }); + pkgInfo.splice(idx, 1); + }); + }); + } + }; + var ignoredConfig = [ + 'bundle', + 'configDependencies', + 'transpiler', + 'treeShaking' + ]; + packages.reverse(); + forEach(packages, function (pkg) { + var steal = pkg.steal || pkg.system; + if (steal) { + var main = steal.main; + delete steal.main; + var configDeps = steal.configDependencies; + if (pkg !== rootPkg) { + forEach(ignoredConfig, function (name) { + delete steal[name]; + }); + } + loader.config(steal); + if (pkg === rootPkg) { + steal.configDependencies = configDeps; + } + steal.main = main; + } + if (pkg.globalBrowser) { + var doNotApplyGlobalBrowser = pkg.name === 'steal' && rootConfig.builtins === false; + if (!doNotApplyGlobalBrowser) { + setGlobalBrowser(pkg.globalBrowser, pkg); + } + } + var systemName = steal && steal.name; + if (systemName) { + setInNpm(systemName, pkg); + } else { + setInNpm(pkg.name, pkg); + } + if (!loader.npm[pkg.name]) { + loader.npm[pkg.name] = pkg; + } + loader.npm[pkg.name + '@' + pkg.version] = pkg; + var pkgAddress = pkg.fileUrl.replace(/\/package\.json.*/, ''); + loader.npmPaths[pkgAddress] = pkg; + }); + setupLiveReload(); + forEach(loader._npmExtensions || [], function (ext) { + if (ext.systemConfig) { + loader.config(ext.systemConfig); + } + }); + }(loader, [ + { + 'name': 'can', + 'version': '5.17.1', + 'fileUrl': './package.json', + 'main': 'can.js', + 'steal': { + 'npmAlgorithm': 'flat', + 'npmIgnore': { + 'bit-docs': true, + 'testee': true, + 'async': true, + 'saucelabs': true, + 'test-saucelabs': true, + 'wd': true, + 'http-server': true + }, + 'meta': { + 'socket.io-client@1.7.4#dist/socket.io': { 'format': 'cjs' }, + 'socket.io-client/dist/socket.io': { 'format': 'cjs' } + }, + 'configDependencies': ['./node_modules/steal-conditional/conditional.js'], + 'main': 'can' + }, + 'resolutions': { + 'can': '5.17.1', + 'can-define': '2.7.1', + 'can-stache-bindings': '4.6.4', + 'can-component': '4.4.9', + 'can-query-logic': '1.1.6', + 'can-value': '1.1.0', + 'can-ajax': '2.1.1', + 'can-construct': '3.5.3', + 'can-bind': '1.1.1', + 'can-construct-super': '3.2.0', + 'can-assign': '1.3.1', + 'can-dom-events': '1.3.3', + 'can-define-lazy-value': '1.1.0', + 'can-deparam': '1.2.0', + 'can-control': '4.4.1', + 'can-globals': '1.2.0', + 'can-event-dom-radiochange': '2.2.0', + 'can-event-queue': '1.1.3', + 'can-event-dom-enter': '2.2.0', + 'can-key-tree': '1.2.0', + 'can-param': '1.1.0', + 'can-key': '1.2.0', + 'can-reflect-dependencies': '1.1.1', + 'can-reflect': '1.17.7', + 'can-parse-uri': '1.2.0', + 'can-queues': '1.2.1', + 'can-reflect-promise': '2.2.0', + 'can-symbol': '1.6.1', + 'can-simple-observable': '2.4.1', + 'can-simple-dom': '1.4.2', + 'can-stache-key': '1.4.0', + 'can-validate-interface': '1.0.2', + 'can-view-scope': '4.11.1', + 'can-view-live': '4.2.7', + 'can-view-model': '4.0.1', + 'can-view-nodelist': '4.3.2', + 'can-view-target': '4.1.2', + 'can-compute': '4.1.0', + 'can-view-parser': '4.1.2', + 'can-stache-converters': '4.2.5', + 'can-kefir': '1.1.2', + 'can-list': '4.2.0', + 'can-stream': '1.1.0', + 'can-map-define': '4.3.4', + 'can-fixture-socket': '2.0.0', + 'can-ndjson-stream': '1.0.0', + 'can-map': '4.3.3', + 'can-validate': '1.2.0', + 'can-stream-kefir': '1.2.0', + 'can-define-stream': '1.1.0', + 'can-define-backup': '2.1.1', + 'can-define-stream-kefir': '1.1.0', + 'can-validate-validatejs': '1.0.0', + 'can-fixture': '3.0.4', + 'can-define-validate-validatejs': '1.1.0', + 'can-view-autorender': '5.0.3' + }, + 'system': { + 'npmAlgorithm': 'flat', + 'npmIgnore': { + 'bit-docs': true, + 'testee': true, + 'async': true, + 'saucelabs': true, + 'test-saucelabs': true, + 'wd': true, + 'http-server': true + }, + 'meta': { + 'socket.io-client@1.7.4#dist/socket.io': { 'format': 'cjs' }, + 'socket.io-client/dist/socket.io': { 'format': 'cjs' } + }, + 'configDependencies': ['./node_modules/steal-conditional/conditional.js'], + 'main': 'can' + } + }, + { + 'name': 'steal', + 'version': '2.1.10', + 'fileUrl': './node_modules/steal/package.json', + 'main': 'main', + 'steal': { + 'npmDependencies': { + 'console-browserify': true, + 'constants-browserify': true, + 'crypto-browserify': true, + 'http-browserify': true, + 'buffer': true, + 'os-browserify': true, + 'vm-browserify': true, + 'zlib-browserify': true, + 'assert': true, + 'domain-browser': true, + 'events': true, + 'https-browserify': true, + 'path-browserify': true, + 'string_decoder': true, + 'tty-browserify': true, + 'process': true, + 'punycode': true + } + }, + 'globalBrowser': { + 'console': 'console-browserify', + 'constants': 'constants-browserify', + 'crypto': 'crypto-browserify', + 'http': 'http-browserify', + 'buffer': 'buffer', + 'os': 'os-browserify', + 'vm': 'vm-browserify', + 'zlib': 'zlib-browserify', + 'assert': 'assert', + 'child_process': 'steal#ext/builtin/child_process', + 'cluster': 'steal#ext/builtin/cluster', + 'dgram': 'steal#ext/builtin/dgram', + 'dns': 'steal#ext/builtin/dns', + 'domain': 'domain-browser', + 'events': 'events', + 'fs': 'steal#ext/builtin/fs', + 'https': 'https-browserify', + 'module': 'steal#ext/builtin/module', + 'net': 'steal#ext/builtin/net', + 'path': 'path-browserify', + 'process': 'process', + 'querystring': 'steal#ext/builtin/querystring', + 'readline': 'steal#ext/builtin/readline', + 'repl': 'steal#ext/builtin/repl', + 'stream': 'steal#ext/builtin/stream', + 'string_decoder': 'string_decoder', + 'sys': 'steal#ext/builtin/sys', + 'timers': 'steal#ext/builtin/timers', + 'tls': 'steal#ext/builtin/tls', + 'tty': 'tty-browserify', + 'url': 'steal#ext/builtin/url', + 'util': 'steal#ext/builtin/util', + '_stream_readable': 'steal#ext/builtin/_stream_readable', + '_stream_writable': 'steal#ext/builtin/_stream_writable', + '_stream_duplex': 'steal#ext/builtin/_stream_duplex', + '_stream_transform': 'steal#ext/builtin/_stream_transform', + '_stream_passthrough': 'steal#ext/builtin/_stream_passthrough' + }, + 'resolutions': {} + }, + { + 'name': 'assert', + 'version': '1.4.1', + 'fileUrl': './node_modules/assert/package.json', + 'main': './assert.js', + 'resolutions': {} + }, + { + 'name': 'buffer', + 'version': '5.0.8', + 'fileUrl': './node_modules/buffer/package.json', + 'main': 'index.js', + 'jspm': {}, + 'resolutions': {} + }, + { + 'name': 'console-browserify', + 'version': '1.1.0', + 'fileUrl': './node_modules/console-browserify/package.json', + 'main': 'index', + 'resolutions': {} + }, + { + 'name': 'constants-browserify', + 'version': '1.0.0', + 'fileUrl': './node_modules/constants-browserify/package.json', + 'main': 'constants.json', + 'resolutions': {} + }, + { + 'name': 'crypto-browserify', + 'version': '3.11.1', + 'fileUrl': './node_modules/crypto-browserify/package.json', + 'browser': { 'crypto': '@empty' }, + 'resolutions': {} + }, + { + 'name': 'domain-browser', + 'version': '1.1.7', + 'fileUrl': './node_modules/domain-browser/package.json', + 'main': './index.js', + 'jspm': {}, + 'resolutions': {} + }, + { + 'name': 'events', + 'version': '1.1.1', + 'fileUrl': './node_modules/events/package.json', + 'main': './events.js', + 'resolutions': {} + }, + { + 'name': 'http-browserify', + 'version': '1.7.0', + 'fileUrl': './node_modules/http-browserify/package.json', + 'main': 'index.js', + 'browser': 'index.js', + 'resolutions': {} + }, + { + 'name': 'https-browserify', + 'version': '1.0.0', + 'fileUrl': './node_modules/https-browserify/package.json', + 'main': 'index.js', + 'resolutions': {} + }, + { + 'name': 'os-browserify', + 'version': '0.3.0', + 'fileUrl': './node_modules/os-browserify/package.json', + 'main': 'main.js', + 'browser': 'browser.js', + 'jspm': {}, + 'resolutions': {} + }, + { + 'name': 'process', + 'version': '0.11.10', + 'fileUrl': './node_modules/process/package.json', + 'main': './index.js', + 'browser': './browser.js', + 'resolutions': {} + }, + { + 'name': 'string_decoder', + 'version': '1.1.1', + 'fileUrl': './node_modules/string_decoder/package.json', + 'main': 'lib/string_decoder.js', + 'resolutions': {} + }, + { + 'name': 'punycode', + 'version': '2.0.1', + 'fileUrl': './node_modules/punycode/package.json', + 'main': 'punycode.js', + 'jspm': {}, + 'resolutions': {} + }, + { + 'name': 'path-browserify', + 'version': '0.0.1', + 'fileUrl': './node_modules/path-browserify/package.json', + 'main': 'index.js', + 'resolutions': {} + }, + { + 'name': 'tty-browserify', + 'version': '0.0.1', + 'fileUrl': './node_modules/tty-browserify/package.json', + 'main': 'index.js', + 'resolutions': {} + }, + { + 'name': 'vm-browserify', + 'version': '0.0.4', + 'fileUrl': './node_modules/vm-browserify/package.json', + 'main': 'index.js', + 'resolutions': {} + }, + { + 'name': 'zlib-browserify', + 'version': '0.0.3', + 'fileUrl': './node_modules/zlib-browserify/package.json', + 'main': 'index.js', + 'resolutions': {} + }, + { + 'name': 'string_decoder', + 'version': '1.0.3', + 'fileUrl': './node_modules/steal/node_modules/string_decoder/package.json', + 'main': 'lib/string_decoder.js', + 'resolutions': {} + }, + { + 'name': 'can-define', + 'version': '2.7.1', + 'fileUrl': './node_modules/can-define/package.json', + 'main': 'can-define.js', + 'resolutions': { + 'can-define': '2.7.1', + 'can-assign': '1.3.1', + 'can-reflect': '1.17.7', + 'can-symbol': '1.6.1', + 'can-queues': '1.2.1', + 'can-simple-observable': '2.4.1', + 'steal-qunit': '1.0.2', + 'can-observation': '4.1.1', + 'can-test-helpers': '1.1.2', + 'can-log': '1.0.0', + 'can-observation-recorder': '1.2.0', + 'can-reflect-tests': '0.2.1', + 'can-construct': '3.5.3', + 'can-namespace': '1.0.0', + 'can-event-queue': '1.1.3', + 'can-string-to-any': '1.2.0', + 'can-define-lazy-value': '1.1.0', + 'can-diff': '1.4.2', + 'can-single-reference': '1.2.0', + 'can-data-types': '1.2.0' + } + }, + { + 'name': 'can-stache-bindings', + 'version': '4.6.4', + 'fileUrl': './node_modules/can-stache-bindings/package.json', + 'main': 'can-stache-bindings', + 'steal': { 'main': 'can-stache-bindings' }, + 'resolutions': { + 'can-stache-bindings': '4.6.4', + 'can-globals': '1.2.0', + 'can-dom-mutate': '1.3.5', + 'can-stache': '4.15.9', + 'steal-qunit': '1.0.2', + 'can-simple-map': '4.3.0', + 'can-dom-events': '1.3.3', + 'can-define': '2.7.1', + 'can-view-callbacks': '4.3.2', + 'can-view-model': '4.0.1', + 'can-symbol': '1.6.1', + 'can-reflect': '1.17.7', + 'can-queues': '1.2.1', + 'can-test-helpers': '1.1.2', + 'can-view-scope': '4.11.1', + 'can-attribute-encoder': '1.1.1', + 'can-simple-observable': '2.4.1', + 'can-dom-data-state': '1.0.5', + 'can-event-dom-enter': '2.2.0', + 'can-reflect-dependencies': '1.1.1', + 'can-bind': '1.1.1', + 'can-stache-key': '1.4.0', + 'can-observation-recorder': '1.2.0', + 'can-assign': '1.3.1', + 'can-log': '1.0.0', + 'can-view-nodelist': '4.3.2', + 'can-vdom': '4.4.0', + 'can-attribute-observable': '1.1.7' + } + }, + { + 'name': 'can-component', + 'version': '4.4.9', + 'fileUrl': './node_modules/can-component/package.json', + 'main': 'can-component', + 'steal': {}, + 'resolutions': { + 'can-component': '4.4.9', + 'can-dom-events': '1.3.3', + 'can-view-model': '4.0.1', + 'can-define': '2.7.1', + 'can-view-scope': '4.11.1', + 'can-simple-observable': '2.4.1', + 'can-reflect': '1.17.7', + 'can-symbol': '1.6.1', + 'can-construct': '3.5.3', + 'can-queues': '1.2.1', + 'can-globals': '1.2.0', + 'can-value': '1.1.0', + 'can-bind': '1.1.1', + 'can-simple-map': '4.3.0', + 'can-dom-mutate': '1.3.5', + 'can-observe': '2.2.0', + 'can-dom-data-state': '1.0.5', + 'can-stache': '4.15.9', + 'can-view-callbacks': '4.3.2', + 'steal-qunit': '1.0.2', + 'can-fragment': '1.3.0', + 'can-log': '1.0.0', + 'can-test-helpers': '1.1.2', + 'can-namespace': '1.0.0', + 'can-stache-bindings': '4.6.4', + 'can-view-nodelist': '4.3.2', + 'can-stache-key': '1.4.0', + 'can-assign': '1.3.1', + 'can-observation-recorder': '1.2.0', + 'can-vdom': '4.4.0', + 'can-child-nodes': '1.2.0', + 'can-string': '1.0.0', + 'can-control': '4.4.1' + } + }, + { + 'name': 'can-query-logic', + 'version': '1.1.6', + 'fileUrl': './node_modules/can-query-logic/package.json', + 'main': 'can-query-logic', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'plugins': [ + 'steal-less', + 'steal-stache' + ] + }, + 'resolutions': { + 'can-query-logic': '1.1.6', + 'can-reflect': '1.17.7', + 'steal-qunit': '1.0.2', + 'can-assign': '1.3.1', + 'can-test-helpers': '1.1.2', + 'can-symbol': '1.6.1', + 'can-key': '1.2.0', + 'can-log': '1.0.0', + 'can-define-lazy-value': '1.1.0' + } + }, + { + 'name': 'can-value', + 'version': '1.1.0', + 'fileUrl': './node_modules/can-value/package.json', + 'main': 'can-value', + 'steal': { + 'npmIgnore': { + 'steal-tools': true, + 'testee': true + }, + 'main': 'can-value' + }, + 'resolutions': { + 'can-value': '1.1.0', + 'can-reflect': '1.17.7', + 'can-reflect-dependencies': '1.1.1', + 'can-simple-map': '4.3.0', + 'steal-qunit': '1.0.2', + 'can-key': '1.2.0', + 'can-simple-observable': '2.4.1', + 'can-namespace': '1.0.0', + 'can-observation': '4.1.1' + } + }, + { + 'name': 'can-ajax', + 'version': '2.1.1', + 'fileUrl': './node_modules/can-ajax/package.json', + 'main': 'dist/cjs/can-ajax', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'steal-tools': true + }, + 'main': 'can-ajax' + }, + 'resolutions': { + 'can-ajax': '2.1.1', + 'can-globals': '1.2.0', + 'can-parse-uri': '1.2.0', + 'can-namespace': '1.0.0', + 'can-make-map': '1.2.0', + 'can-reflect': '1.17.7', + 'can-param': '1.1.0', + 'steal-qunit': '1.0.2', + 'qunitjs': '2.4.1' + } + }, + { + 'name': 'can-construct', + 'version': '3.5.3', + 'fileUrl': './node_modules/can-construct/package.json', + 'main': 'can-construct', + 'steal': {}, + 'resolutions': { + 'can-construct': '3.5.3', + 'steal-qunit': '1.0.2', + 'can-log': '1.0.0', + 'can-reflect': '1.17.7', + 'can-namespace': '1.0.0', + 'can-string': '1.0.0' + } + }, + { + 'name': 'can-bind', + 'version': '1.1.1', + 'fileUrl': './node_modules/can-bind/package.json', + 'main': 'can-bind', + 'steal': { + 'npmIgnore': { + 'steal-tools': true, + 'testee': true + }, + 'main': 'can-bind' + }, + 'resolutions': { + 'can-bind': '1.1.1', + 'can-reflect': '1.17.7', + 'can-reflect-dependencies': '1.1.1', + 'can-simple-observable': '2.4.1', + 'can-simple-map': '4.3.0', + 'can-value': '1.1.0', + 'can-test-helpers': '1.1.2', + 'can-observation': '4.1.1', + 'steal-qunit': '1.0.2', + 'can-symbol': '1.6.1', + 'can-namespace': '1.0.0', + 'can-queues': '1.2.1', + 'can-assign': '1.3.1', + 'can-log': '1.0.0' + } + }, + { + 'name': 'can-construct-super', + 'version': '3.2.0', + 'fileUrl': './node_modules/can-construct-super/package.json', + 'main': 'can-construct-super', + 'steal': { + 'npmIgnore': { + 'documentjs': true, + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'main': 'can-construct-super' + }, + 'resolutions': { + 'can-construct-super': '3.2.0', + 'steal-qunit': '1.0.2', + 'can-reflect': '1.17.7', + 'can-construct': '3.5.3' + } + }, + { + 'name': 'can-assign', + 'version': '1.3.1', + 'fileUrl': './node_modules/can-assign/package.json', + 'main': 'dist/cjs/can-assign', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'main': 'can-assign' + }, + 'resolutions': { + 'can-assign': '1.3.1', + 'steal-qunit': '1.0.2', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-dom-events', + 'version': '1.3.3', + 'fileUrl': './node_modules/can-dom-events/package.json', + 'main': 'can-dom-events', + 'resolutions': { + 'can-dom-events': '1.3.3', + 'steal-qunit': '1.0.2', + 'can-namespace': '1.0.0', + 'jquery': '3.3.1', + 'can-globals': '1.2.0', + 'can-key-tree': '1.2.0', + 'can-reflect': '1.17.7' + } + }, + { + 'name': 'can-define-lazy-value', + 'version': '1.1.0', + 'fileUrl': './node_modules/can-define-lazy-value/package.json', + 'main': 'define-lazy-value', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'steal-tools': true + } + }, + 'resolutions': { + 'can-define-lazy-value': '1.1.0', + 'steal-qunit': '1.0.2' + } + }, + { + 'name': 'can-deparam', + 'version': '1.2.0', + 'fileUrl': './node_modules/can-deparam/package.json', + 'main': 'can-deparam', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + } + }, + 'resolutions': { + 'can-deparam': '1.2.0', + 'can-string-to-any': '1.2.0', + 'steal-qunit': '1.0.2', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-control', + 'version': '4.4.1', + 'fileUrl': './node_modules/can-control/package.json', + 'main': 'can-control', + 'resolutions': { + 'can-control': '4.4.1', + 'can-dom-events': '1.3.3', + 'can-globals': '1.2.0', + 'can-define': '2.7.1', + 'can-simple-observable': '2.4.1', + 'can-symbol': '1.6.1', + 'can-simple-map': '4.3.0', + 'can-log': '1.0.0', + 'can-util': '3.14.0', + 'can-dom-mutate': '1.3.5', + 'steal-qunit': '1.0.2', + 'can-construct': '3.5.3', + 'can-namespace': '1.0.0', + 'can-assign': '1.3.1', + 'can-stache-key': '1.4.0', + 'can-reflect': '1.17.7', + 'can-observation': '4.1.1', + 'can-event-queue': '1.1.3', + 'can-key': '1.2.0', + 'can-string': '1.0.0' + } + }, + { + 'name': 'can-globals', + 'version': '1.2.0', + 'fileUrl': './node_modules/can-globals/package.json', + 'main': 'can-globals.js', + 'resolutions': { + 'can-globals': '1.2.0', + 'can-reflect': '1.17.7', + 'qunitjs': '2.4.1', + 'steal-qunit': '1.0.2', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-event-dom-radiochange', + 'version': '2.2.0', + 'fileUrl': './node_modules/can-event-dom-radiochange/package.json', + 'main': 'can-event-dom-radiochange', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'steal-tools': true + }, + 'main': 'can-event-dom-radiochange' + }, + 'resolutions': { + 'can-dom-events': '1.3.3', + 'can-event-dom-radiochange': '2.2.0', + 'can-namespace': '1.0.0', + 'steal-qunit': '1.0.2', + 'can-globals': '1.2.0' + } + }, + { + 'name': 'can-event-queue', + 'version': '1.1.3', + 'fileUrl': './node_modules/can-event-queue/package.json', + 'main': './can-event-queue.js', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'plugins': [ + 'steal-less', + 'steal-stache' + ] + }, + 'resolutions': { + 'can-event-queue': '1.1.3', + 'can-reflect': '1.17.7', + 'can-symbol': '1.6.1', + 'can-queues': '1.2.1', + 'can-dom-events': '1.3.3', + 'steal-qunit': '1.0.2', + 'can-log': '1.0.0', + 'can-key-tree': '1.2.0', + 'can-define-lazy-value': '1.1.0' + } + }, + { + 'name': 'can-event-dom-enter', + 'version': '2.2.0', + 'fileUrl': './node_modules/can-event-dom-enter/package.json', + 'main': 'can-event-dom-enter', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'steal-tools': true + }, + 'main': 'can-event-dom-enter' + }, + 'resolutions': { + 'can-dom-events': '1.3.3', + 'can-event-dom-enter': '2.2.0', + 'steal-qunit': '1.0.2', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-key-tree', + 'version': '1.2.0', + 'fileUrl': './node_modules/can-key-tree/package.json', + 'main': 'dist/cjs/can-key-tree', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'plugins': [ + 'steal-less', + 'steal-stache' + ], + 'main': 'can-key-tree' + }, + 'resolutions': { + 'can-key-tree': '1.2.0', + 'can-reflect': '1.17.7', + 'steal-qunit': '1.0.2' + } + }, + { + 'name': 'can-param', + 'version': '1.1.0', + 'fileUrl': './node_modules/can-param/package.json', + 'main': 'can-param', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + } + }, + 'resolutions': { + 'can-param': '1.1.0', + 'steal-qunit': '1.0.2', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-key', + 'version': '1.2.0', + 'fileUrl': './node_modules/can-key/package.json', + 'main': 'can-key', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'plugins': [ + 'steal-less', + 'steal-stache' + ], + 'main': 'can-key' + }, + 'resolutions': { + 'can-key': '1.2.0', + 'can-reflect': '1.17.7', + 'steal-qunit': '1.0.2', + 'can-symbol': '1.6.1', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-reflect-dependencies', + 'version': '1.1.1', + 'fileUrl': './node_modules/can-reflect-dependencies/package.json', + 'main': 'can-reflect-dependencies.js', + 'resolutions': { + 'can-simple-observable': '2.4.1', + 'can-reflect-dependencies': '1.1.1', + 'steal-qunit': '1.0.2', + 'can-simple-map': '4.3.0', + 'can-reflect': '1.17.7', + 'can-symbol': '1.6.1', + 'can-assign': '1.3.1' + } + }, + { + 'name': 'can-reflect', + 'version': '1.17.7', + 'fileUrl': './node_modules/can-reflect/package.json', + 'main': 'can-reflect', + 'resolutions': { + 'can-reflect': '1.17.7', + 'can-symbol': '1.6.1', + 'can-namespace': '1.0.0', + 'steal-qunit': '1.0.2' + } + }, + { + 'name': 'can-parse-uri', + 'version': '1.2.0', + 'fileUrl': './node_modules/can-parse-uri/package.json', + 'main': 'can-parse-uri', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'main': 'can-parse-uri' + }, + 'resolutions': { + 'can-parse-uri': '1.2.0', + 'steal-qunit': '1.0.2', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-queues', + 'version': '1.2.1', + 'fileUrl': './node_modules/can-queues/package.json', + 'main': './can-queues.js', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'main': 'can-queues' + }, + 'resolutions': { + 'can-queues': '1.2.1', + 'can-test-helpers': '1.1.2', + 'steal-qunit': '1.0.2', + 'can-log': '1.0.0', + 'can-namespace': '1.0.0', + 'can-assign': '1.3.1' + } + }, + { + 'name': 'can-reflect-promise', + 'version': '2.2.0', + 'fileUrl': './node_modules/can-reflect-promise/package.json', + 'main': 'can-reflect-promise', + 'steal': { 'npmAlgorithm': 'flat' }, + 'resolutions': { + 'can-globals': '1.2.0', + 'can-symbol': '1.6.1', + 'can-reflect-promise': '2.2.0', + 'can-test-helpers': '1.1.2', + 'can-observation-recorder': '1.2.0', + 'steal-qunit': '1.0.2', + 'can-reflect': '1.17.7', + 'can-queues': '1.2.1', + 'can-key-tree': '1.2.0', + 'can-log': '1.0.0' + } + }, + { + 'name': 'can-symbol', + 'version': '1.6.1', + 'fileUrl': './node_modules/can-symbol/package.json', + 'main': 'can-symbol', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'main': 'can-symbol' + }, + 'resolutions': { + 'can-symbol': '1.6.1', + 'steal-qunit': '1.0.2', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-simple-observable', + 'version': '2.4.1', + 'fileUrl': './node_modules/can-simple-observable/package.json', + 'main': 'can-simple-observable', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'steal-tools': true + } + }, + 'resolutions': { + 'can-symbol': '1.6.1', + 'can-simple-observable': '2.4.1', + 'can-reflect': '1.17.7', + 'steal-qunit': '1.0.2', + 'can-observation-recorder': '1.2.0', + 'can-namespace': '1.0.0', + 'can-event-queue': '1.1.3', + 'can-observation': '4.1.1', + 'can-queues': '1.2.1', + 'can-key': '1.2.0', + 'can-reflect-dependencies': '1.1.1', + 'can-log': '1.0.0' + } + }, + { + 'name': 'can-simple-dom', + 'version': '1.4.2', + 'fileUrl': './node_modules/can-simple-dom/package.json', + 'main': 'can-simple-dom.js', + 'resolutions': { + 'can-simple-dom': '1.4.2', + 'steal-qunit': '1.0.2', + 'simple-html-tokenizer': '0.2.6', + 'he': '1.2.0', + 'micro-location': '0.1.5' + } + }, + { + 'name': 'can-stache-key', + 'version': '1.4.0', + 'fileUrl': './node_modules/can-stache-key/package.json', + 'main': 'can-stache-key', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'main': 'can-stache-key' + }, + 'resolutions': { + 'can-stache-key': '1.4.0', + 'can-event-queue': '1.1.3', + 'can-simple-observable': '2.4.1', + 'can-reflect': '1.17.7', + 'can-test-helpers': '1.1.2', + 'can-observation': '4.1.1', + 'steal-qunit': '1.0.2', + 'can-observation-recorder': '1.2.0', + 'can-simple-map': '4.3.0', + 'can-log': '1.0.0', + 'can-symbol': '1.6.1', + 'can-reflect-promise': '2.2.0' + } + }, + { + 'name': 'can-validate-interface', + 'version': '1.0.2', + 'fileUrl': './node_modules/can-validate-interface/package.json', + 'main': 'index.js', + 'resolutions': { + 'can-validate-interface': '1.0.2', + 'steal-qunit': '1.0.2' + } + }, + { + 'name': 'can-view-scope', + 'version': '4.11.1', + 'fileUrl': './node_modules/can-view-scope/package.json', + 'main': 'can-view-scope', + 'resolutions': { + 'can-view-scope': '4.11.1', + 'can-stache-key': '1.4.0', + 'can-symbol': '1.6.1', + 'can-reflect': '1.17.7', + 'can-simple-observable': '2.4.1', + 'can-reflect-dependencies': '1.1.1', + 'can-simple-map': '4.3.0', + 'can-test-helpers': '1.1.2', + 'can-observation': '4.1.1', + 'can-stache-helpers': '1.2.0', + 'steal-qunit': '1.0.2', + 'can-observation-recorder': '1.2.0', + 'can-assign': '1.3.1', + 'can-namespace': '1.0.0', + 'can-log': '1.0.0', + 'can-define-lazy-value': '1.1.0', + 'can-single-reference': '1.2.0', + 'can-event-queue': '1.1.3' + } + }, + { + 'name': 'can-view-live', + 'version': '4.2.7', + 'fileUrl': './node_modules/can-view-live/package.json', + 'main': 'can-view-live', + 'steal': { + 'npmIgnore': { + 'documentjs': true, + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'main': 'can-view-live' + }, + 'resolutions': { + 'can-view-live': '4.2.7', + 'can-define': '2.7.1', + 'can-symbol': '1.6.1', + 'can-simple-observable': '2.4.1', + 'can-observation': '4.1.1', + 'can-view-nodelist': '4.3.2', + 'can-test-helpers': '1.1.2', + 'can-dom-mutate': '1.3.5', + 'can-reflect-dependencies': '1.1.1', + 'can-queues': '1.2.1', + 'can-globals': '1.2.0', + 'can-simple-map': '4.3.0', + 'can-reflect': '1.17.7', + 'steal-qunit': '1.0.2', + 'can-fragment': '1.3.0', + 'can-diff': '1.4.2', + 'can-attribute-observable': '1.1.7', + 'can-view-parser': '4.1.2', + 'can-view-callbacks': '4.3.2', + 'can-child-nodes': '1.2.0' + } + }, + { + 'name': 'can-view-model', + 'version': '4.0.1', + 'fileUrl': './node_modules/can-view-model/package.json', + 'main': 'can-view-model', + 'resolutions': { + 'can-view-model': '4.0.1', + 'can-simple-map': '4.3.0', + 'steal-qunit': '1.0.2', + 'can-namespace': '1.0.0', + 'can-globals': '1.2.0', + 'can-reflect': '1.17.7', + 'can-symbol': '1.6.1' + } + }, + { + 'name': 'can-view-nodelist', + 'version': '4.3.2', + 'fileUrl': './node_modules/can-view-nodelist/package.json', + 'main': 'can-view-nodelist', + 'resolutions': { + 'can-view-nodelist': '4.3.2', + 'can-reflect': '1.17.7', + 'can-fragment': '1.3.0', + 'steal-qunit': '1.0.2', + 'can-namespace': '1.0.0', + 'can-dom-mutate': '1.3.5' + } + }, + { + 'name': 'can-view-target', + 'version': '4.1.2', + 'fileUrl': './node_modules/can-view-target/package.json', + 'main': 'can-view-target', + 'resolutions': { + 'can-view-target': '4.1.2', + 'can-simple-dom': '1.4.2', + 'can-globals': '1.2.0', + 'steal-qunit': '1.0.2', + 'can-dom-mutate': '1.3.5', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-compute', + 'version': '4.1.0', + 'fileUrl': './node_modules/can-compute/package.json', + 'main': 'can-compute', + 'resolutions': { + 'can-compute': '4.1.0', + 'can-symbol': '1.6.1', + 'can-reflect': '1.17.7', + 'can-event-queue': '1.1.3', + 'can-queues': '1.2.1', + 'can-dom-events': '1.3.3', + 'steal-qunit': '1.0.2', + 'can-observation-recorder': '1.2.0', + 'can-namespace': '1.0.0', + 'can-single-reference': '1.2.0', + 'can-observation': '4.1.1', + 'can-stache-key': '1.4.0', + 'can-key': '1.2.0', + 'can-assign': '1.3.1' + } + }, + { + 'name': 'can-view-parser', + 'version': '4.1.2', + 'fileUrl': './node_modules/can-view-parser/package.json', + 'main': 'can-view-parser', + 'resolutions': { + 'can-view-parser': '4.1.2', + 'can-attribute-encoder': '1.1.1', + 'steal-qunit': '1.0.2', + 'can-log': '1.0.0', + 'can-test-helpers': '1.1.2', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-stache-converters', + 'version': '4.2.5', + 'fileUrl': './node_modules/can-stache-converters/package.json', + 'main': 'can-stache-converters', + 'steal': { 'main': 'can-stache-converters' }, + 'resolutions': { + 'can-stache-converters': '4.2.5', + 'can-define': '2.7.1', + 'can-dom-events': '1.3.3', + 'can-reflect': '1.17.7', + 'can-compute': '4.1.0', + 'can-stache': '4.15.9', + 'steal-qunit': '1.0.2', + 'can-string-to-any': '1.2.0', + 'can-log': '1.0.0', + 'can-stache-bindings': '4.6.4', + 'can-stache-helpers': '1.2.0' + } + }, + { + 'name': 'can-kefir', + 'version': '1.1.2', + 'fileUrl': './node_modules/can-kefir/package.json', + 'main': 'can-kefir', + 'browser': {}, + 'resolutions': { + 'can-kefir': '1.1.2', + 'can-queues': '1.2.1', + 'can-reflect': '1.17.7', + 'steal-qunit': '1.0.2', + 'can-symbol': '1.6.1', + 'can-event-queue': '1.1.3', + 'can-observation-recorder': '1.2.0', + 'kefir': '3.8.5' + } + }, + { + 'name': 'can-list', + 'version': '4.2.0', + 'fileUrl': './node_modules/can-list/package.json', + 'main': 'can-list', + 'steal': { 'npmAlgorithm': 'flat' }, + 'resolutions': { + 'can-list': '4.2.0', + 'can-map': '4.3.3', + 'can-reflect': '1.17.7', + 'can-symbol': '1.6.1', + 'steal-qunit': '1.0.2', + 'can-observation': '4.1.1', + 'can-namespace': '1.0.0', + 'can-queues': '1.2.1', + 'can-event-queue': '1.1.3', + 'can-observation-recorder': '1.2.0', + 'can-assign': '1.3.1', + 'can-cid': '1.3.0', + 'can-types': '1.4.0' + } + }, + { + 'name': 'can-stream', + 'version': '1.1.0', + 'fileUrl': './node_modules/can-stream/package.json', + 'main': 'can-stream', + 'steal': {}, + 'resolutions': { + 'can-compute': '4.1.0', + 'can-define': '2.7.1', + 'can-stream': '1.1.0', + 'steal-qunit': '1.0.2', + 'can-assign': '1.3.1', + 'can-reflect': '1.17.7', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-map-define', + 'version': '4.3.4', + 'fileUrl': './node_modules/can-map-define/package.json', + 'main': 'can-map-define', + 'steal': { 'main': 'can-map-define' }, + 'resolutions': { + 'can-key': '1.2.0', + 'can-map': '4.3.3', + 'can-list': '4.2.0', + 'can-compute': '4.1.0', + 'can-reflect': '1.17.7', + 'can-map-define': '4.3.4', + 'can-reflect-tests': '0.2.1', + 'steal-qunit': '1.0.2', + 'can-log': '1.0.0', + 'can-assign': '1.3.1', + 'can-event-queue': '1.1.3', + 'can-queues': '1.2.1', + 'can-observation-recorder': '1.2.0' + } + }, + { + 'name': 'can-fixture-socket', + 'version': '2.0.0', + 'fileUrl': './node_modules/can-fixture-socket/package.json', + 'main': 'can-fixture-socket', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'main': 'can-fixture-socket' + }, + 'resolutions': { + 'can-fixture-socket': '2.0.0', + 'can-fixture': '3.0.4', + 'feathers-socketio': '1.6.0', + 'can-set-legacy': '1.0.0', + 'feathers-hooks': '2.1.2', + 'socket.io-client': '1.7.4', + 'feathers': '2.2.4', + 'es6-promise-polyfill': '1.2.0', + 'object-assign': '4.1.0', + 'steal-qunit': '1.0.2', + 'can-assign': '1.3.1' + } + }, + { + 'name': 'can-ndjson-stream', + 'version': '1.0.0', + 'fileUrl': './node_modules/can-ndjson-stream/package.json', + 'main': 'can-ndjson-stream', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'main': 'can-ndjson-stream' + }, + 'resolutions': { + 'can-ndjson-stream': '1.0.0', + 'steal-qunit': '1.0.2', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-map', + 'version': '4.3.3', + 'fileUrl': './node_modules/can-map/package.json', + 'main': 'can-map', + 'steal': {}, + 'resolutions': { + 'can-map': '4.3.3', + 'can-compute': '4.1.0', + 'can-construct': '3.5.3', + 'can-stache-key': '1.4.0', + 'can-reflect': '1.17.7', + 'can-symbol': '1.6.1', + 'can-queues': '1.2.1', + 'can-observation-recorder': '1.2.0', + 'can-reflect-tests': '0.2.1', + 'steal-qunit': '1.0.2', + 'can-event-queue': '1.1.3', + 'can-namespace': '1.0.0', + 'can-log': '1.0.0', + 'can-assign': '1.3.1', + 'can-single-reference': '1.2.0', + 'can-cid': '1.3.0', + 'can-types': '1.4.0' + } + }, + { + 'name': 'can-validate', + 'version': '1.2.0', + 'fileUrl': './node_modules/can-validate/package.json', + 'main': 'can-validate.js', + 'steal': { + 'ignoreBrowser': true, + 'npmIgnore': { + 'documentjs': true, + 'testee': true, + 'steal-tools': true + }, + 'npmDependencies': { 'steal-qunit': true } + }, + 'browser': {}, + 'resolutions': { + 'can-validate': '1.2.0', + 'steal-qunit': '1.0.2', + 'can-reflect': '1.17.7' + } + }, + { + 'name': 'can-stream-kefir', + 'version': '1.2.0', + 'fileUrl': './node_modules/can-stream-kefir/package.json', + 'main': 'can-stream-kefir', + 'steal': {}, + 'resolutions': { + 'can-stream-kefir': '1.2.0', + 'can-compute': '4.1.0', + 'can-reflect': '1.17.7', + 'can-define': '2.7.1', + 'steal-qunit': '1.0.2', + 'can-kefir': '1.1.2', + 'can-stream': '1.1.0', + 'can-symbol': '1.6.1', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-define-stream', + 'version': '1.1.0', + 'fileUrl': './node_modules/can-define-stream/package.json', + 'main': 'can-define-stream', + 'steal': {}, + 'resolutions': { + 'can-define': '2.7.1', + 'can-define-stream': '1.1.0', + 'can-compute': '4.1.0', + 'can-stream': '1.1.0', + 'can-symbol': '1.6.1', + 'steal-qunit': '1.0.2', + 'can-assign': '1.3.1', + 'can-reflect': '1.17.7' + } + }, + { + 'name': 'can-define-backup', + 'version': '2.1.1', + 'fileUrl': './node_modules/can-define-backup/package.json', + 'main': 'can-define-backup', + 'resolutions': { + 'can-define': '2.7.1', + 'can-reflect': '1.17.7', + 'can-define-backup': '2.1.1', + 'can-observation': '4.1.1', + 'steal-qunit': '1.0.2', + 'can-simple-observable': '2.4.1', + 'can-diff': '1.4.2' + } + }, + { + 'name': 'can-define-stream-kefir', + 'version': '1.1.0', + 'fileUrl': './node_modules/can-define-stream-kefir/package.json', + 'main': 'can-define-stream-kefir', + 'steal': {}, + 'resolutions': { + 'can-define': '2.7.1', + 'can-define-stream-kefir': '1.1.0', + 'can-symbol': '1.6.1', + 'steal-qunit': '1.0.2', + 'can-namespace': '1.0.0', + 'can-define-stream': '1.1.0', + 'can-stream-kefir': '1.2.0' + } + }, + { + 'name': 'can-validate-validatejs', + 'version': '1.0.0', + 'fileUrl': './node_modules/can-validate-validatejs/package.json', + 'main': 'can-validate-validatejs.js', + 'steal': { + 'ignoreBrowser': true, + 'npmIgnore': { + 'bit-docs': true, + 'testee': true, + 'steal-tools': true + }, + 'npmDependencies': { 'steal-qunit': true }, + 'paths': { 'validate.js@0.11.1#validate': './node_modules/validate.js/validate.js' } + }, + 'resolutions': { + 'can-validate-validatejs': '1.0.0', + 'steal-qunit': '1.0.2', + 'can-reflect': '1.17.7', + 'validate.js': '0.11.1' + }, + 'system': { + 'ignoreBrowser': true, + 'npmIgnore': { + 'bit-docs': true, + 'testee': true, + 'steal-tools': true + }, + 'npmDependencies': { 'steal-qunit': true }, + 'paths': { 'validate.js@0.11.1#validate': './node_modules/validate.js/validate.js' } + } + }, + { + 'name': 'can-fixture', + 'version': '3.0.4', + 'fileUrl': './node_modules/can-fixture/package.json', + 'main': 'fixture.js', + 'resolutions': { + 'can-fixture': '3.0.4', + 'can-reflect': '1.17.7', + 'can-query-logic': '1.1.6', + 'jquery': '3.3.1', + 'steal-qunit': '1.0.2', + 'can-set-legacy': '1.0.0', + 'can-log': '1.0.0', + 'can-test-helpers': '1.1.2', + 'can-namespace': '1.0.0', + 'can-key': '1.2.0', + 'can-deparam': '1.2.0', + 'can-memory-store': '1.0.1' + } + }, + { + 'name': 'can-define-validate-validatejs', + 'version': '1.1.0', + 'fileUrl': './node_modules/can-define-validate-validatejs/package.json', + 'main': 'can-define-validate-validatejs.js', + 'steal': { + 'ignoreBrowser': true, + 'npmIgnore': { + 'documentjs': true, + 'testee': true, + 'steal-tools': true + }, + 'npmDependencies': { 'steal-qunit': true } + }, + 'browser': {}, + 'resolutions': { + 'can-define-validate-validatejs': '1.1.0', + 'can-define': '2.7.1', + 'can-compute': '4.1.0', + 'steal-qunit': '1.0.2', + 'can-assign': '1.3.1', + 'can-reflect': '1.17.7', + 'can-validate': '1.2.0', + 'can-validate-validatejs': '0.1.3' + } + }, + { + 'name': 'can-view-autorender', + 'version': '5.0.3', + 'fileUrl': './node_modules/can-view-autorender/package.json', + 'main': 'can-view-autorender', + 'resolutions': { + 'can-view-autorender': '5.0.3', + 'steal-qunit': '1.0.2' + } + }, + { + 'name': 'steal-qunit', + 'version': '1.0.2', + 'fileUrl': './node_modules/steal-qunit/package.json', + 'main': 'steal-qunit', + 'steal': { + 'plugins': ['steal-css'], + 'meta': { + 'qunitjs@1.23.1#qunit/qunit': { + 'format': 'global', + 'exports': 'QUnit', + 'deps': ['steal-qunit/add-dom'] + } + } + }, + 'resolutions': { + 'qunitjs': '1.23.1', + 'steal-css': '1.3.2' + }, + 'system': { + 'plugins': ['steal-css'], + 'meta': { + 'qunitjs@1.23.1#qunit/qunit': { + 'format': 'global', + 'exports': 'QUnit', + 'deps': ['steal-qunit/add-dom'] + } + } + } + }, + { + 'name': 'can-simple-map', + 'version': '4.3.0', + 'fileUrl': './node_modules/can-simple-map/package.json', + 'main': 'can-simple-map', + 'steal': { + 'npmIgnore': { + 'documentjs': true, + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'main': 'can-simple-map' + }, + 'resolutions': { + 'can-construct': '3.5.3', + 'can-event-queue': '1.1.3', + 'can-queues': '1.2.1', + 'can-observation-recorder': '1.2.0', + 'can-reflect': '1.17.7', + 'can-log': '1.0.0', + 'can-symbol': '1.6.1' + } + }, + { + 'name': 'can-namespace', + 'version': '1.0.0', + 'fileUrl': './node_modules/can-namespace/package.json', + 'main': 'can-namespace', + 'steal': { 'npmAlgorithm': 'flat' }, + 'resolutions': {} + }, + { + 'name': 'can-make-map', + 'version': '1.2.0', + 'fileUrl': './node_modules/can-make-map/package.json', + 'main': 'dist/cjs/can-make-map', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'main': 'can-make-map' + }, + 'resolutions': {} + }, + { + 'name': 'can-log', + 'version': '1.0.0', + 'fileUrl': './node_modules/can-log/package.json', + 'main': 'dist/cjs/can-log', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'main': 'can-log' + }, + 'resolutions': { 'can-log': '1.0.0' } + }, + { + 'name': 'can-util', + 'version': '3.14.0', + 'fileUrl': './node_modules/can-util/package.json', + 'main': 'can-util', + 'resolutions': { + 'can-globals': '1.2.0', + 'can-util': '3.14.0', + 'can-namespace': '1.0.0', + 'can-symbol': '1.6.1' + } + }, + { + 'name': 'can-dom-mutate', + 'version': '1.3.5', + 'fileUrl': './node_modules/can-dom-mutate/package.json', + 'main': 'can-dom-mutate', + 'steal': { 'main': 'can-dom-mutate' }, + 'resolutions': { + 'can-globals': '1.2.0', + 'can-namespace': '1.0.0', + 'can-reflect': '1.17.7', + 'can-dom-mutate': '1.3.5' + } + }, + { + 'name': 'can-string-to-any', + 'version': '1.2.0', + 'fileUrl': './node_modules/can-string-to-any/package.json', + 'main': 'can-string-to-any', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'main': 'can-string-to-any' + }, + 'resolutions': {} + }, + { + 'name': 'can-test-helpers', + 'version': '1.1.2', + 'fileUrl': './node_modules/can-test-helpers/package.json', + 'main': 'can-test-helpers.js', + 'resolutions': { + 'can-test-helpers': '1.1.2', + 'can-log': '1.0.0', + 'can-util': '3.14.0' + } + }, + { + 'name': 'can-observation-recorder', + 'version': '1.2.0', + 'fileUrl': './node_modules/can-observation-recorder/package.json', + 'main': './can-observation-recorder.js', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + } + }, + 'resolutions': { + 'can-namespace': '1.0.0', + 'can-symbol': '1.6.1' + } + }, + { + 'name': 'can-observation', + 'version': '4.1.1', + 'fileUrl': './node_modules/can-observation/package.json', + 'main': 'can-observation', + 'steal': { 'npmAlgorithm': 'flat' }, + 'resolutions': { + 'can-namespace': '1.0.0', + 'can-reflect': '1.17.7', + 'can-queues': '1.2.1', + 'can-observation-recorder': '1.2.0', + 'can-symbol': '1.6.1', + 'can-log': '1.0.0', + 'can-event-queue': '1.1.3', + 'can-observation': '4.1.1' + } + }, + { + 'name': 'can-fragment', + 'version': '1.3.0', + 'fileUrl': './node_modules/can-fragment/package.json', + 'main': 'can-fragment', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + } + }, + 'resolutions': { + 'can-globals': '1.2.0', + 'can-namespace': '1.0.0', + 'can-reflect': '1.17.7', + 'can-symbol': '1.6.1', + 'can-child-nodes': '1.2.0' + } + }, + { + 'name': 'can-stache-helpers', + 'version': '1.2.0', + 'fileUrl': './node_modules/can-stache-helpers/package.json', + 'main': 'can-stache-helpers', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + } + }, + 'resolutions': { 'can-namespace': '1.0.0' } + }, + { + 'name': 'can-reflect-tests', + 'version': '0.2.1', + 'fileUrl': './node_modules/can-reflect-tests/package.json', + 'main': 'can-reflect-tests', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'plugins': [ + 'steal-less', + 'steal-stache' + ], + 'main': 'can-reflect-tests' + }, + 'resolutions': { + 'can-reflect-tests': '0.2.1', + 'steal-qunit': '1.0.2', + 'can-symbol': '1.6.1', + 'can-reflect': '1.17.7' + } + }, + { + 'name': 'can-attribute-encoder', + 'version': '1.1.1', + 'fileUrl': './node_modules/can-attribute-encoder/package.json', + 'main': 'can-attribute-encoder', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'steal-tools': true + }, + 'main': 'can-attribute-encoder' + }, + 'resolutions': { + 'can-namespace': '1.0.0', + 'can-log': '1.0.0' + } + }, + { + 'name': 'feathers-socketio', + 'version': '1.6.0', + 'fileUrl': './node_modules/feathers-socketio/package.json', + 'main': 'lib/', + 'browser': { 'feathers-socketio#lib/index': 'feathers-socketio#lib/client' }, + 'resolutions': { + 'feathers-socketio': '1.6.0', + 'feathers-socket-commons': '2.4.0' + } + }, + { + 'name': 'can-set-legacy', + 'version': '1.0.0', + 'fileUrl': './node_modules/can-set-legacy/package.json', + 'main': 'can-set-legacy', + 'resolutions': { + 'can-query-logic': '1.1.6', + 'can-reflect': '1.17.7', + 'can-key': '1.2.0' + } + }, + { + 'name': 'feathers-hooks', + 'version': '2.1.2', + 'fileUrl': './node_modules/feathers-hooks/package.json', + 'main': 'lib/hooks.js', + 'resolutions': { + 'feathers-hooks': '2.1.2', + 'uberproto': '1.2.0', + 'feathers-commons': '0.8.7' + } + }, + { + 'name': 'socket.io-client', + 'version': '1.7.4', + 'fileUrl': './node_modules/socket.io-client/package.json', + 'main': './lib/index', + 'resolutions': { + 'socket.io-client': '1.7.4', + 'socket.io-parser': '2.3.1', + 'debug': '2.3.3', + 'backo2': '1.0.2', + 'engine.io-client': '1.8.5', + 'component-bind': '1.0.0', + 'parseuri': '0.0.5', + 'has-binary': '0.1.7', + 'to-array': '0.1.4', + 'component-emitter': '1.2.1', + 'indexof': '0.0.1' + } + }, + { + 'name': 'feathers', + 'version': '2.2.4', + 'fileUrl': './node_modules/feathers/package.json', + 'main': 'lib/index', + 'browser': { 'feathers#lib/index': 'feathers#lib/client/index' }, + 'resolutions': { + 'feathers': '2.2.4', + 'uberproto': '1.2.0', + 'events': '1.1.1', + 'feathers-commons': '0.8.7', + 'babel-runtime': '6.26.0', + 'debug': '3.2.6', + 'rubberduck': '1.1.1' + } + }, + { + 'name': 'es6-promise-polyfill', + 'version': '1.2.0', + 'fileUrl': './node_modules/es6-promise-polyfill/package.json', + 'main': 'promise.js', + 'resolutions': {} + }, + { + 'name': 'jquery', + 'version': '3.3.1', + 'fileUrl': './node_modules/jquery/package.json', + 'main': 'dist/jquery.js', + 'resolutions': {} + }, + { + 'name': 'object-assign', + 'version': '4.1.0', + 'fileUrl': './node_modules/object-assign/package.json', + 'resolutions': {} + }, + { + 'name': 'can-observe', + 'version': '2.2.0', + 'fileUrl': './node_modules/can-observe/package.json', + 'main': 'can-observe.js', + 'resolutions': { + 'can-observe': '2.2.0', + 'can-reflect': '1.17.7', + 'can-observation-recorder': '1.2.0', + 'can-event-queue': '1.1.3', + 'can-symbol': '1.6.1', + 'can-observation': '4.1.1', + 'can-simple-observable': '2.4.1', + 'can-queues': '1.2.1' + } + }, + { + 'name': 'can-dom-data-state', + 'version': '1.0.5', + 'fileUrl': './node_modules/can-dom-data-state/package.json', + 'main': 'can-dom-data-state.js', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'main': 'can-dom-data-state' + }, + 'resolutions': { + 'can-namespace': '1.0.0', + 'can-dom-mutate': '1.3.5', + 'can-cid': '1.3.0' + } + }, + { + 'name': 'can-stache', + 'version': '4.15.9', + 'fileUrl': './node_modules/can-stache/package.json', + 'main': 'can-stache', + 'resolutions': { + 'can-view-parser': '4.1.2', + 'can-view-callbacks': '4.3.2', + 'can-stache': '4.15.9', + 'can-attribute-encoder': '1.1.1', + 'can-log': '1.0.0', + 'can-namespace': '1.0.0', + 'can-globals': '1.2.0', + 'can-assign': '1.3.1', + 'can-reflect': '1.17.7', + 'can-view-scope': '4.11.1', + 'can-observation-recorder': '1.2.0', + 'can-symbol': '1.6.1', + 'can-view-target': '4.1.2', + 'can-view-nodelist': '4.3.2', + 'can-stache-ast': '1.1.0', + 'can-import-module': '1.2.0', + 'can-view-live': '4.2.7', + 'can-observation': '4.1.1', + 'can-fragment': '1.3.0', + 'can-dom-mutate': '1.3.5', + 'can-define-lazy-value': '1.1.0', + 'can-stache-helpers': '1.2.0', + 'can-dom-data-state': '1.0.5', + 'can-stache-key': '1.4.0', + 'can-join-uris': '1.2.0', + 'can-dom-data': '1.0.1', + 'can-simple-observable': '2.4.1' + } + }, + { + 'name': 'can-view-callbacks', + 'version': '4.3.2', + 'fileUrl': './node_modules/can-view-callbacks/package.json', + 'main': 'can-view-callbacks', + 'resolutions': { + 'can-observation-recorder': '1.2.0', + 'can-log': '1.0.0', + 'can-globals': '1.2.0', + 'can-dom-mutate': '1.3.5', + 'can-namespace': '1.0.0', + 'can-view-nodelist': '4.3.2', + 'can-fragment': '1.3.0', + 'can-symbol': '1.6.1', + 'can-reflect': '1.17.7' + } + }, + { + 'name': 'steal-css', + 'version': '1.3.2', + 'fileUrl': './node_modules/steal-css/package.json', + 'main': 'css.js', + 'steal': { + 'ext': { 'css': 'steal-css' }, + 'map': { '$css': 'steal-css@1.3.2#css' } + }, + 'resolutions': {} + }, + { + 'name': 'qunitjs', + 'version': '2.4.1', + 'fileUrl': './node_modules/qunitjs/package.json', + 'main': 'qunit/qunit.js', + 'resolutions': {} + }, + { + 'name': 'qunitjs', + 'version': '1.23.1', + 'fileUrl': './node_modules/steal-qunit/node_modules/qunitjs/package.json', + 'main': 'qunit/qunit.js', + 'resolutions': { 'steal-qunit': '1.0.2' } + }, + { + 'name': 'can-string', + 'version': '1.0.0', + 'fileUrl': './node_modules/can-string/package.json', + 'main': 'can-string', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'plugins': [ + 'steal-less', + 'steal-stache' + ] + }, + 'resolutions': {} + }, + { + 'name': 'can-single-reference', + 'version': '1.2.0', + 'fileUrl': './node_modules/can-single-reference/package.json', + 'main': 'can-single-reference', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + } + }, + 'resolutions': { 'can-cid': '1.3.0' } + }, + { + 'name': 'can-cid', + 'version': '1.3.0', + 'fileUrl': './node_modules/can-cid/package.json', + 'main': 'can-cid', + 'resolutions': { + 'can-namespace': '1.0.0', + 'can-cid': '1.3.0' + } + }, + { + 'name': 'can-types', + 'version': '1.4.0', + 'fileUrl': './node_modules/can-types/package.json', + 'main': 'can-types', + 'resolutions': { + 'can-namespace': '1.0.0', + 'can-reflect': '1.17.7', + 'can-symbol': '1.6.1', + 'can-log': '1.0.0' + } + }, + { + 'name': 'socket.io-parser', + 'version': '2.3.1', + 'fileUrl': './node_modules/socket.io-parser/package.json', + 'resolutions': { + 'socket.io-parser': '2.3.1', + 'json3': '3.3.2', + 'debug': '2.2.0', + 'component-emitter': '1.1.2', + 'isarray': '0.0.1' + } + }, + { + 'name': 'kefir', + 'version': '3.8.5', + 'fileUrl': './node_modules/kefir/package.json', + 'main': 'dist/kefir.js', + 'resolutions': {} + }, + { + 'name': 'uberproto', + 'version': '1.2.0', + 'fileUrl': './node_modules/uberproto/package.json', + 'main': 'lib/proto', + 'resolutions': {} + }, + { + 'name': 'feathers-commons', + 'version': '0.8.7', + 'fileUrl': './node_modules/feathers-commons/package.json', + 'main': 'lib/commons.js', + 'resolutions': { 'feathers-commons': '0.8.7' } + }, + { + 'name': 'can-diff', + 'version': '1.4.2', + 'fileUrl': './node_modules/can-diff/package.json', + 'main': 'can-diff', + 'steal': { 'main': 'can-diff' }, + 'resolutions': { + 'can-reflect': '1.17.7', + 'can-key-tree': '1.2.0', + 'can-symbol': '1.6.1', + 'can-diff': '1.4.2', + 'can-queues': '1.2.1' + } + }, + { + 'name': 'can-stache-ast', + 'version': '1.1.0', + 'fileUrl': './node_modules/can-stache-ast/package.json', + 'main': 'can-stache-ast.js', + 'resolutions': { + 'can-stache-ast': '1.1.0', + 'can-view-parser': '4.1.2' + } + }, + { + 'name': 'can-import-module', + 'version': '1.2.0', + 'fileUrl': './node_modules/can-import-module/package.json', + 'main': 'can-import-module.js', + 'resolutions': { + 'can-globals': '1.2.0', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-vdom', + 'version': '4.4.0', + 'fileUrl': './node_modules/can-vdom/package.json', + 'main': 'can-vdom.js', + 'steal': { + 'map': { 'can-vdom@4.4.0#assert': 'chai/chai' }, + 'meta': { + 'chai/chai': { + 'format': 'global', + 'exports': 'chai.assert' + } + }, + 'plugins': ['chai'], + 'main': 'can-vdom' + }, + 'resolutions': { + 'can-simple-dom': '1.4.2', + 'can-vdom': '4.4.0', + 'can-view-parser': '4.1.2' + } + }, + { + 'name': 'can-attribute-observable', + 'version': '1.1.7', + 'fileUrl': './node_modules/can-attribute-observable/package.json', + 'main': 'can-attribute-observable', + 'resolutions': { + 'can-queues': '1.2.1', + 'can-attribute-observable': '1.1.7', + 'can-reflect': '1.17.7', + 'can-observation': '4.1.1', + 'can-reflect-dependencies': '1.1.1', + 'can-observation-recorder': '1.2.0', + 'can-simple-observable': '2.4.1', + 'can-assign': '1.3.1', + 'can-dom-events': '1.3.3', + 'can-event-dom-radiochange': '2.2.0', + 'can-globals': '1.2.0', + 'can-dom-data-state': '1.0.5', + 'can-dom-mutate': '1.3.5', + 'can-diff': '1.4.2' + } + }, + { + 'name': 'simple-html-tokenizer', + 'version': '0.2.6', + 'fileUrl': './node_modules/simple-html-tokenizer/package.json', + 'main': 'dist/simple-html-tokenizer.js', + 'resolutions': { 'simple-html-tokenizer': '0.2.6' } + }, + { + 'name': 'he', + 'version': '1.2.0', + 'fileUrl': './node_modules/he/package.json', + 'main': 'he.js', + 'resolutions': {} + }, + { + 'name': 'can-child-nodes', + 'version': '1.2.0', + 'fileUrl': './node_modules/can-child-nodes/package.json', + 'main': 'can-child-nodes', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + } + }, + 'resolutions': { 'can-namespace': '1.0.0' } + }, + { + 'name': 'validate.js', + 'version': '0.11.1', + 'fileUrl': './node_modules/validate.js/package.json', + 'main': 'validate.js', + 'resolutions': {} + }, + { + 'name': 'can-validate-validatejs', + 'version': '0.1.3', + 'fileUrl': './node_modules/can-define-validate-validatejs/node_modules/can-validate-validatejs/package.json', + 'main': 'can-validate-validatejs.js', + 'steal': { + 'ignoreBrowser': true, + 'npmIgnore': { + 'bit-docs': true, + 'testee': true, + 'steal-tools': true + }, + 'npmDependencies': { 'steal-qunit': true }, + 'paths': { 'validate.js@0.11.1#validate': './node_modules/validate.js/validate.js' } + }, + 'resolutions': { + 'can-reflect': '1.17.7', + 'validate.js': '0.11.1' + } + }, + { + 'name': 'can-data-types', + 'version': '1.2.0', + 'fileUrl': './node_modules/can-data-types/package.json', + 'main': 'can-data-types', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'main': 'can-data-types' + }, + 'resolutions': { 'can-reflect': '1.17.7' } + }, + { + 'name': 'can-memory-store', + 'version': '1.0.1', + 'fileUrl': './node_modules/can-memory-store/package.json', + 'main': 'can-memory-store', + 'resolutions': { + 'can-reflect': '1.17.7', + 'can-namespace': '1.0.0', + 'can-memory-store': '1.0.1' + } + }, + { + 'name': 'feathers-socket-commons', + 'version': '2.4.0', + 'fileUrl': './node_modules/feathers-socket-commons/package.json', + 'main': 'lib/', + 'resolutions': { + 'feathers-socket-commons': '2.4.0', + 'debug': '2.3.3', + 'feathers-errors': '2.9.2', + 'feathers-commons': '0.8.7' + } + }, + { + 'name': 'debug', + 'version': '2.3.3', + 'fileUrl': './node_modules/socket.io-client/node_modules/debug/package.json', + 'main': './index.js', + 'browser': './browser.js', + 'resolutions': { + 'debug': '2.3.3', + 'ms': '0.7.2' + } + }, + { + 'name': 'micro-location', + 'version': '0.1.5', + 'fileUrl': './node_modules/micro-location/package.json', + 'main': 'lib/micro-location.js', + 'resolutions': {} + }, + { + 'name': 'can-join-uris', + 'version': '1.2.0', + 'fileUrl': './node_modules/can-join-uris/package.json', + 'main': 'can-join-uris', + 'steal': {}, + 'resolutions': { + 'can-namespace': '1.0.0', + 'can-parse-uri': '1.2.0' + } + }, + { + 'name': 'can-dom-data', + 'version': '1.0.1', + 'fileUrl': './node_modules/can-dom-data/package.json', + 'main': 'can-dom-data.js', + 'steal': { + 'npmIgnore': { + 'steal-tools': true, + 'testee': true + }, + 'main': 'can-dom-data' + }, + 'resolutions': { 'can-namespace': '1.0.0' } + }, + { + 'name': 'json3', + 'version': '3.3.2', + 'fileUrl': './node_modules/json3/package.json', + 'main': './lib/json3', + 'jam': { 'main': './lib/json3.js' }, + 'resolutions': {} + }, + { + 'name': 'debug', + 'version': '2.2.0', + 'fileUrl': './node_modules/socket.io-parser/node_modules/debug/package.json', + 'main': './node.js', + 'browser': './browser.js', + 'resolutions': { + 'debug': '2.2.0', + 'ms': '0.7.1' + } + }, + { + 'name': 'backo2', + 'version': '1.0.2', + 'fileUrl': './node_modules/backo2/package.json', + 'resolutions': {} + }, + { + 'name': 'engine.io-client', + 'version': '1.8.5', + 'fileUrl': './node_modules/engine.io-client/package.json', + 'browser': { + 'ws': '@empty', + 'xmlhttprequest-ssl': 'engine.io-client#lib/xmlhttprequest' + }, + 'resolutions': { + 'engine.io-client': '1.8.5', + 'engine.io-parser': '1.3.2', + 'component-emitter': '1.2.1', + 'debug': '2.3.3', + 'indexof': '0.0.1', + 'parseuri': '0.0.5', + 'parseqs': '0.0.5', + 'parsejson': '0.0.3', + 'yeast': '0.1.2', + 'component-inherit': '0.0.3', + 'has-cors': '1.1.0' + } + }, + { + 'name': 'component-bind', + 'version': '1.0.0', + 'fileUrl': './node_modules/component-bind/package.json', + 'resolutions': {} + }, + { + 'name': 'parseuri', + 'version': '0.0.5', + 'fileUrl': './node_modules/parseuri/package.json', + 'resolutions': {} + }, + { + 'name': 'has-binary', + 'version': '0.1.7', + 'fileUrl': './node_modules/has-binary/package.json', + 'resolutions': { 'isarray': '0.0.1' } + }, + { + 'name': 'to-array', + 'version': '0.1.4', + 'fileUrl': './node_modules/to-array/package.json', + 'main': 'index', + 'resolutions': {} + }, + { + 'name': 'babel-runtime', + 'version': '6.26.0', + 'fileUrl': './node_modules/babel-runtime/package.json', + 'resolutions': { 'core-js': '2.5.7' } + }, + { + 'name': 'component-emitter', + 'version': '1.2.1', + 'fileUrl': './node_modules/component-emitter/package.json', + 'main': 'index.js', + 'resolutions': {} + }, + { + 'name': 'debug', + 'version': '3.2.6', + 'fileUrl': './node_modules/feathers/node_modules/debug/package.json', + 'main': './src/index.js', + 'browser': './src/browser.js', + 'resolutions': { + 'debug': '3.2.6', + 'ms': '2.1.1' + } + }, + { + 'name': 'indexof', + 'version': '0.0.1', + 'fileUrl': './node_modules/indexof/package.json', + 'resolutions': {} + }, + { + 'name': 'component-emitter', + 'version': '1.1.2', + 'fileUrl': './node_modules/socket.io-parser/node_modules/component-emitter/package.json', + 'main': 'index.js', + 'resolutions': {} + }, + { + 'name': 'feathers-errors', + 'version': '2.9.2', + 'fileUrl': './node_modules/feathers-errors/package.json', + 'main': 'lib/index', + 'resolutions': { 'debug': '3.2.6' } + }, + { + 'name': 'core-js', + 'version': '2.5.7', + 'fileUrl': './node_modules/core-js/package.json', + 'main': 'index.js', + 'resolutions': { 'core-js': '2.5.7' } + }, + { + 'name': 'ms', + 'version': '0.7.2', + 'fileUrl': './node_modules/socket.io-client/node_modules/ms/package.json', + 'main': './index', + 'resolutions': {} + }, + { + 'name': 'isarray', + 'version': '0.0.1', + 'fileUrl': './node_modules/has-binary/node_modules/isarray/package.json', + 'main': 'index.js', + 'resolutions': {} + }, + { + 'name': 'rubberduck', + 'version': '1.1.1', + 'fileUrl': './node_modules/rubberduck/package.json', + 'main': 'lib/rubberduck', + 'resolutions': { + 'events': '1.1.1', + 'rubberduck': '1.1.1' + } + }, + { + 'name': 'engine.io-parser', + 'version': '1.3.2', + 'fileUrl': './node_modules/engine.io-parser/package.json', + 'browser': './lib/browser.js', + 'resolutions': { + 'engine.io-parser': '1.3.2', + 'has-binary': '0.1.7', + 'arraybuffer.slice': '0.0.6', + 'after': '0.8.2', + 'base64-arraybuffer': '0.1.5', + 'blob': '0.0.4', + 'wtf-8': '1.0.0' + } + }, + { + 'name': 'ms', + 'version': '2.1.1', + 'fileUrl': './node_modules/feathers/node_modules/ms/package.json', + 'main': './index', + 'resolutions': {} + }, + { + 'name': 'ms', + 'version': '0.7.1', + 'fileUrl': './node_modules/socket.io-parser/node_modules/ms/package.json', + 'main': './index', + 'resolutions': {} + }, + { + 'name': 'arraybuffer.slice', + 'version': '0.0.6', + 'fileUrl': './node_modules/arraybuffer.slice/package.json', + 'resolutions': {} + }, + { + 'name': 'after', + 'version': '0.8.2', + 'fileUrl': './node_modules/after/package.json', + 'resolutions': {} + }, + { + 'name': 'base64-arraybuffer', + 'version': '0.1.5', + 'fileUrl': './node_modules/base64-arraybuffer/package.json', + 'main': 'lib/base64-arraybuffer', + 'resolutions': {} + }, + { + 'name': 'blob', + 'version': '0.0.4', + 'fileUrl': './node_modules/blob/package.json', + 'resolutions': {} + }, + { + 'name': 'parseqs', + 'version': '0.0.5', + 'fileUrl': './node_modules/parseqs/package.json', + 'resolutions': {} + }, + { + 'name': 'wtf-8', + 'version': '1.0.0', + 'fileUrl': './node_modules/wtf-8/package.json', + 'main': 'wtf-8.js', + 'resolutions': {} + }, + { + 'name': 'parsejson', + 'version': '0.0.3', + 'fileUrl': './node_modules/parsejson/package.json', + 'resolutions': {} + }, + { + 'name': 'yeast', + 'version': '0.1.2', + 'fileUrl': './node_modules/yeast/package.json', + 'main': 'index.js', + 'resolutions': {} + }, + { + 'name': 'component-inherit', + 'version': '0.0.3', + 'fileUrl': './node_modules/component-inherit/package.json', + 'resolutions': {} + }, + { + 'name': 'has-cors', + 'version': '1.1.0', + 'fileUrl': './node_modules/has-cors/package.json', + 'main': 'index.js', + 'resolutions': {} + } + ], { 'npmParentMap': {} })); +}); +/*steal-qunit@1.0.2#add-dom*/ +define('steal-qunit@1.0.2#add-dom', function (require, exports, module) { + 'format cjs'; + if (!document.getElementById('qunit')) { + var qunit = document.createElement('div'); + qunit.id = 'qunit'; + (document.body || document.documentElement).appendChild(qunit); + } +}); +/*qunitjs@1.23.1#qunit/qunit*/ +define('qunitjs@1.23.1#qunit/qunit', [ + 'module', + '@loader', + 'require', + 'steal-qunit/add-dom' +], function (module, loader, require) { + loader.get('@@global-helpers').prepareGlobal({ + require: require, + name: module.id, + deps: ['steal-qunit/add-dom'], + exports: 'QUnit' + }); + var define = loader.global.define; + var require = loader.global.require; + var source = '/*!\n * QUnit 1.23.1\n * https://qunitjs.com/\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license\n * https://jquery.org/license\n *\n * Date: 2016-04-12T17:29Z\n */\n\n( function( global ) {\n\nvar QUnit = {};\n\nvar Date = global.Date;\nvar now = Date.now || function() {\n\treturn new Date().getTime();\n};\n\nvar setTimeout = global.setTimeout;\nvar clearTimeout = global.clearTimeout;\n\n// Store a local window from the global to allow direct references.\nvar window = global.window;\n\nvar defined = {\n\tdocument: window && window.document !== undefined,\n\tsetTimeout: setTimeout !== undefined,\n\tsessionStorage: ( function() {\n\t\tvar x = "qunit-test-string";\n\t\ttry {\n\t\t\tsessionStorage.setItem( x, x );\n\t\t\tsessionStorage.removeItem( x );\n\t\t\treturn true;\n\t\t} catch ( e ) {\n\t\t\treturn false;\n\t\t}\n\t}() )\n};\n\nvar fileName = ( sourceFromStacktrace( 0 ) || "" ).replace( /(:\\d+)+\\)?/, "" ).replace( /.+\\//, "" );\nvar globalStartCalled = false;\nvar runStarted = false;\n\nvar toString = Object.prototype.toString,\n\thasOwn = Object.prototype.hasOwnProperty;\n\n// Returns a new Array with the elements that are in a but not in b\nfunction diff( a, b ) {\n\tvar i, j,\n\t\tresult = a.slice();\n\n\tfor ( i = 0; i < result.length; i++ ) {\n\t\tfor ( j = 0; j < b.length; j++ ) {\n\t\t\tif ( result[ i ] === b[ j ] ) {\n\t\t\t\tresult.splice( i, 1 );\n\t\t\t\ti--;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn result;\n}\n\n// From jquery.js\nfunction inArray( elem, array ) {\n\tif ( array.indexOf ) {\n\t\treturn array.indexOf( elem );\n\t}\n\n\tfor ( var i = 0, length = array.length; i < length; i++ ) {\n\t\tif ( array[ i ] === elem ) {\n\t\t\treturn i;\n\t\t}\n\t}\n\n\treturn -1;\n}\n\n/**\n * Makes a clone of an object using only Array or Object as base,\n * and copies over the own enumerable properties.\n *\n * @param {Object} obj\n * @return {Object} New object with only the own properties (recursively).\n */\nfunction objectValues ( obj ) {\n\tvar key, val,\n\t\tvals = QUnit.is( "array", obj ) ? [] : {};\n\tfor ( key in obj ) {\n\t\tif ( hasOwn.call( obj, key ) ) {\n\t\t\tval = obj[ key ];\n\t\t\tvals[ key ] = val === Object( val ) ? objectValues( val ) : val;\n\t\t}\n\t}\n\treturn vals;\n}\n\nfunction extend( a, b, undefOnly ) {\n\tfor ( var prop in b ) {\n\t\tif ( hasOwn.call( b, prop ) ) {\n\n\t\t\t// Avoid "Member not found" error in IE8 caused by messing with window.constructor\n\t\t\t// This block runs on every environment, so `global` is being used instead of `window`\n\t\t\t// to avoid errors on node.\n\t\t\tif ( prop !== "constructor" || a !== global ) {\n\t\t\t\tif ( b[ prop ] === undefined ) {\n\t\t\t\t\tdelete a[ prop ];\n\t\t\t\t} else if ( !( undefOnly && typeof a[ prop ] !== "undefined" ) ) {\n\t\t\t\t\ta[ prop ] = b[ prop ];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn a;\n}\n\nfunction objectType( obj ) {\n\tif ( typeof obj === "undefined" ) {\n\t\treturn "undefined";\n\t}\n\n\t// Consider: typeof null === object\n\tif ( obj === null ) {\n\t\treturn "null";\n\t}\n\n\tvar match = toString.call( obj ).match( /^\\[object\\s(.*)\\]$/ ),\n\t\ttype = match && match[ 1 ];\n\n\tswitch ( type ) {\n\t\tcase "Number":\n\t\t\tif ( isNaN( obj ) ) {\n\t\t\t\treturn "nan";\n\t\t\t}\n\t\t\treturn "number";\n\t\tcase "String":\n\t\tcase "Boolean":\n\t\tcase "Array":\n\t\tcase "Set":\n\t\tcase "Map":\n\t\tcase "Date":\n\t\tcase "RegExp":\n\t\tcase "Function":\n\t\tcase "Symbol":\n\t\t\treturn type.toLowerCase();\n\t}\n\tif ( typeof obj === "object" ) {\n\t\treturn "object";\n\t}\n}\n\n// Safe object type checking\nfunction is( type, obj ) {\n\treturn QUnit.objectType( obj ) === type;\n}\n\n// Doesn\'t support IE6 to IE9, it will return undefined on these browsers\n// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack\nfunction extractStacktrace( e, offset ) {\n\toffset = offset === undefined ? 4 : offset;\n\n\tvar stack, include, i;\n\n\tif ( e.stack ) {\n\t\tstack = e.stack.split( "\\n" );\n\t\tif ( /^error$/i.test( stack[ 0 ] ) ) {\n\t\t\tstack.shift();\n\t\t}\n\t\tif ( fileName ) {\n\t\t\tinclude = [];\n\t\t\tfor ( i = offset; i < stack.length; i++ ) {\n\t\t\t\tif ( stack[ i ].indexOf( fileName ) !== -1 ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tinclude.push( stack[ i ] );\n\t\t\t}\n\t\t\tif ( include.length ) {\n\t\t\t\treturn include.join( "\\n" );\n\t\t\t}\n\t\t}\n\t\treturn stack[ offset ];\n\n\t// Support: Safari <=6 only\n\t} else if ( e.sourceURL ) {\n\n\t\t// Exclude useless self-reference for generated Error objects\n\t\tif ( /qunit.js$/.test( e.sourceURL ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// For actual exceptions, this is useful\n\t\treturn e.sourceURL + ":" + e.line;\n\t}\n}\n\nfunction sourceFromStacktrace( offset ) {\n\tvar error = new Error();\n\n\t// Support: Safari <=7 only, IE <=10 - 11 only\n\t// Not all browsers generate the `stack` property for `new Error()`, see also #636\n\tif ( !error.stack ) {\n\t\ttry {\n\t\t\tthrow error;\n\t\t} catch ( err ) {\n\t\t\terror = err;\n\t\t}\n\t}\n\n\treturn extractStacktrace( error, offset );\n}\n\n/**\n * Config object: Maintain internal state\n * Later exposed as QUnit.config\n * `config` initialized at top of scope\n */\nvar config = {\n\n\t// The queue of tests to run\n\tqueue: [],\n\n\t// Block until document ready\n\tblocking: true,\n\n\t// By default, run previously failed tests first\n\t// very useful in combination with "Hide passed tests" checked\n\treorder: true,\n\n\t// By default, modify document.title when suite is done\n\taltertitle: true,\n\n\t// HTML Reporter: collapse every test except the first failing test\n\t// If false, all failing tests will be expanded\n\tcollapse: true,\n\n\t// By default, scroll to top of the page when suite is done\n\tscrolltop: true,\n\n\t// Depth up-to which object will be dumped\n\tmaxDepth: 5,\n\n\t// When enabled, all tests must call expect()\n\trequireExpects: false,\n\n\t// Placeholder for user-configurable form-exposed URL parameters\n\turlConfig: [],\n\n\t// Set of all modules.\n\tmodules: [],\n\n\t// Stack of nested modules\n\tmoduleStack: [],\n\n\t// The first unnamed module\n\tcurrentModule: {\n\t\tname: "",\n\t\ttests: []\n\t},\n\n\tcallbacks: {}\n};\n\n// Push a loose unnamed module to the modules collection\nconfig.modules.push( config.currentModule );\n\nvar loggingCallbacks = {};\n\n// Register logging callbacks\nfunction registerLoggingCallbacks( obj ) {\n\tvar i, l, key,\n\t\tcallbackNames = [ "begin", "done", "log", "testStart", "testDone",\n\t\t\t"moduleStart", "moduleDone" ];\n\n\tfunction registerLoggingCallback( key ) {\n\t\tvar loggingCallback = function( callback ) {\n\t\t\tif ( objectType( callback ) !== "function" ) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t"QUnit logging methods require a callback function as their first parameters."\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconfig.callbacks[ key ].push( callback );\n\t\t};\n\n\t\t// DEPRECATED: This will be removed on QUnit 2.0.0+\n\t\t// Stores the registered functions allowing restoring\n\t\t// at verifyLoggingCallbacks() if modified\n\t\tloggingCallbacks[ key ] = loggingCallback;\n\n\t\treturn loggingCallback;\n\t}\n\n\tfor ( i = 0, l = callbackNames.length; i < l; i++ ) {\n\t\tkey = callbackNames[ i ];\n\n\t\t// Initialize key collection of logging callback\n\t\tif ( objectType( config.callbacks[ key ] ) === "undefined" ) {\n\t\t\tconfig.callbacks[ key ] = [];\n\t\t}\n\n\t\tobj[ key ] = registerLoggingCallback( key );\n\t}\n}\n\nfunction runLoggingCallbacks( key, args ) {\n\tvar i, l, callbacks;\n\n\tcallbacks = config.callbacks[ key ];\n\tfor ( i = 0, l = callbacks.length; i < l; i++ ) {\n\t\tcallbacks[ i ]( args );\n\t}\n}\n\n// DEPRECATED: This will be removed on 2.0.0+\n// This function verifies if the loggingCallbacks were modified by the user\n// If so, it will restore it, assign the given callback and print a console warning\nfunction verifyLoggingCallbacks() {\n\tvar loggingCallback, userCallback;\n\n\tfor ( loggingCallback in loggingCallbacks ) {\n\t\tif ( QUnit[ loggingCallback ] !== loggingCallbacks[ loggingCallback ] ) {\n\n\t\t\tuserCallback = QUnit[ loggingCallback ];\n\n\t\t\t// Restore the callback function\n\t\t\tQUnit[ loggingCallback ] = loggingCallbacks[ loggingCallback ];\n\n\t\t\t// Assign the deprecated given callback\n\t\t\tQUnit[ loggingCallback ]( userCallback );\n\n\t\t\tif ( global.console && global.console.warn ) {\n\t\t\t\tglobal.console.warn(\n\t\t\t\t\t"QUnit." + loggingCallback + " was replaced with a new value.\\n" +\n\t\t\t\t\t"Please, check out the documentation on how to apply logging callbacks.\\n" +\n\t\t\t\t\t"Reference: https://api.qunitjs.com/category/callbacks/"\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n}\n\n( function() {\n\tif ( !defined.document ) {\n\t\treturn;\n\t}\n\n\t// `onErrorFnPrev` initialized at top of scope\n\t// Preserve other handlers\n\tvar onErrorFnPrev = window.onerror;\n\n\t// Cover uncaught exceptions\n\t// Returning true will suppress the default browser handler,\n\t// returning false will let it run.\n\twindow.onerror = function( error, filePath, linerNr ) {\n\t\tvar ret = false;\n\t\tif ( onErrorFnPrev ) {\n\t\t\tret = onErrorFnPrev( error, filePath, linerNr );\n\t\t}\n\n\t\t// Treat return value as window.onerror itself does,\n\t\t// Only do our handling if not suppressed.\n\t\tif ( ret !== true ) {\n\t\t\tif ( QUnit.config.current ) {\n\t\t\t\tif ( QUnit.config.current.ignoreGlobalErrors ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tQUnit.pushFailure( error, filePath + ":" + linerNr );\n\t\t\t} else {\n\t\t\t\tQUnit.test( "global failure", extend( function() {\n\t\t\t\t\tQUnit.pushFailure( error, filePath + ":" + linerNr );\n\t\t\t\t}, { validTest: true } ) );\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\treturn ret;\n\t};\n}() );\n\n// Figure out if we\'re running the tests from a server or not\nQUnit.isLocal = !( defined.document && window.location.protocol !== "file:" );\n\n// Expose the current QUnit version\nQUnit.version = "1.23.1";\n\nextend( QUnit, {\n\n\t// Call on start of module test to prepend name to all tests\n\tmodule: function( name, testEnvironment, executeNow ) {\n\t\tvar module, moduleFns;\n\t\tvar currentModule = config.currentModule;\n\n\t\tif ( arguments.length === 2 ) {\n\t\t\tif ( objectType( testEnvironment ) === "function" ) {\n\t\t\t\texecuteNow = testEnvironment;\n\t\t\t\ttestEnvironment = undefined;\n\t\t\t}\n\t\t}\n\n\t\t// DEPRECATED: handles setup/teardown functions,\n\t\t// beforeEach and afterEach should be used instead\n\t\tif ( testEnvironment && testEnvironment.setup ) {\n\t\t\ttestEnvironment.beforeEach = testEnvironment.setup;\n\t\t\tdelete testEnvironment.setup;\n\t\t}\n\t\tif ( testEnvironment && testEnvironment.teardown ) {\n\t\t\ttestEnvironment.afterEach = testEnvironment.teardown;\n\t\t\tdelete testEnvironment.teardown;\n\t\t}\n\n\t\tmodule = createModule();\n\n\t\tmoduleFns = {\n\t\t\tbeforeEach: setHook( module, "beforeEach" ),\n\t\t\tafterEach: setHook( module, "afterEach" )\n\t\t};\n\n\t\tif ( objectType( executeNow ) === "function" ) {\n\t\t\tconfig.moduleStack.push( module );\n\t\t\tsetCurrentModule( module );\n\t\t\texecuteNow.call( module.testEnvironment, moduleFns );\n\t\t\tconfig.moduleStack.pop();\n\t\t\tmodule = module.parentModule || currentModule;\n\t\t}\n\n\t\tsetCurrentModule( module );\n\n\t\tfunction createModule() {\n\t\t\tvar parentModule = config.moduleStack.length ?\n\t\t\t\tconfig.moduleStack.slice( -1 )[ 0 ] : null;\n\t\t\tvar moduleName = parentModule !== null ?\n\t\t\t\t[ parentModule.name, name ].join( " > " ) : name;\n\t\t\tvar module = {\n\t\t\t\tname: moduleName,\n\t\t\t\tparentModule: parentModule,\n\t\t\t\ttests: [],\n\t\t\t\tmoduleId: generateHash( moduleName )\n\t\t\t};\n\n\t\t\tvar env = {};\n\t\t\tif ( parentModule ) {\n\t\t\t\textend( env, parentModule.testEnvironment );\n\t\t\t\tdelete env.beforeEach;\n\t\t\t\tdelete env.afterEach;\n\t\t\t}\n\t\t\textend( env, testEnvironment );\n\t\t\tmodule.testEnvironment = env;\n\n\t\t\tconfig.modules.push( module );\n\t\t\treturn module;\n\t\t}\n\n\t\tfunction setCurrentModule( module ) {\n\t\t\tconfig.currentModule = module;\n\t\t}\n\n\t},\n\n\t// DEPRECATED: QUnit.asyncTest() will be removed in QUnit 2.0.\n\tasyncTest: asyncTest,\n\n\ttest: test,\n\n\tskip: skip,\n\n\tonly: only,\n\n\t// DEPRECATED: The functionality of QUnit.start() will be altered in QUnit 2.0.\n\t// In QUnit 2.0, invoking it will ONLY affect the `QUnit.config.autostart` blocking behavior.\n\tstart: function( count ) {\n\t\tvar globalStartAlreadyCalled = globalStartCalled;\n\n\t\tif ( !config.current ) {\n\t\t\tglobalStartCalled = true;\n\n\t\t\tif ( runStarted ) {\n\t\t\t\tthrow new Error( "Called start() outside of a test context while already started" );\n\t\t\t} else if ( globalStartAlreadyCalled || count > 1 ) {\n\t\t\t\tthrow new Error( "Called start() outside of a test context too many times" );\n\t\t\t} else if ( config.autostart ) {\n\t\t\t\tthrow new Error( "Called start() outside of a test context when " +\n\t\t\t\t\t"QUnit.config.autostart was true" );\n\t\t\t} else if ( !config.pageLoaded ) {\n\n\t\t\t\t// The page isn\'t completely loaded yet, so bail out and let `QUnit.load` handle it\n\t\t\t\tconfig.autostart = true;\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else {\n\n\t\t\t// If a test is running, adjust its semaphore\n\t\t\tconfig.current.semaphore -= count || 1;\n\n\t\t\t// If semaphore is non-numeric, throw error\n\t\t\tif ( isNaN( config.current.semaphore ) ) {\n\t\t\t\tconfig.current.semaphore = 0;\n\n\t\t\t\tQUnit.pushFailure(\n\t\t\t\t\t"Called start() with a non-numeric decrement.",\n\t\t\t\t\tsourceFromStacktrace( 2 )\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Don\'t start until equal number of stop-calls\n\t\t\tif ( config.current.semaphore > 0 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Throw an Error if start is called more often than stop\n\t\t\tif ( config.current.semaphore < 0 ) {\n\t\t\t\tconfig.current.semaphore = 0;\n\n\t\t\t\tQUnit.pushFailure(\n\t\t\t\t\t"Called start() while already started (test\'s semaphore was 0 already)",\n\t\t\t\t\tsourceFromStacktrace( 2 )\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tresumeProcessing();\n\t},\n\n\t// DEPRECATED: QUnit.stop() will be removed in QUnit 2.0.\n\tstop: function( count ) {\n\n\t\t// If there isn\'t a test running, don\'t allow QUnit.stop() to be called\n\t\tif ( !config.current ) {\n\t\t\tthrow new Error( "Called stop() outside of a test context" );\n\t\t}\n\n\t\t// If a test is running, adjust its semaphore\n\t\tconfig.current.semaphore += count || 1;\n\n\t\tpauseProcessing();\n\t},\n\n\tconfig: config,\n\n\tis: is,\n\n\tobjectType: objectType,\n\n\textend: extend,\n\n\tload: function() {\n\t\tconfig.pageLoaded = true;\n\n\t\t// Initialize the configuration options\n\t\textend( config, {\n\t\t\tstats: { all: 0, bad: 0 },\n\t\t\tmoduleStats: { all: 0, bad: 0 },\n\t\t\tstarted: 0,\n\t\t\tupdateRate: 1000,\n\t\t\tautostart: true,\n\t\t\tfilter: ""\n\t\t}, true );\n\n\t\tconfig.blocking = false;\n\n\t\tif ( config.autostart ) {\n\t\t\tresumeProcessing();\n\t\t}\n\t},\n\n\tstack: function( offset ) {\n\t\toffset = ( offset || 0 ) + 2;\n\t\treturn sourceFromStacktrace( offset );\n\t}\n} );\n\nregisterLoggingCallbacks( QUnit );\n\nfunction begin() {\n\tvar i, l,\n\t\tmodulesLog = [];\n\n\t// If the test run hasn\'t officially begun yet\n\tif ( !config.started ) {\n\n\t\t// Record the time of the test run\'s beginning\n\t\tconfig.started = now();\n\n\t\tverifyLoggingCallbacks();\n\n\t\t// Delete the loose unnamed module if unused.\n\t\tif ( config.modules[ 0 ].name === "" && config.modules[ 0 ].tests.length === 0 ) {\n\t\t\tconfig.modules.shift();\n\t\t}\n\n\t\t// Avoid unnecessary information by not logging modules\' test environments\n\t\tfor ( i = 0, l = config.modules.length; i < l; i++ ) {\n\t\t\tmodulesLog.push( {\n\t\t\t\tname: config.modules[ i ].name,\n\t\t\t\ttests: config.modules[ i ].tests\n\t\t\t} );\n\t\t}\n\n\t\t// The test run is officially beginning now\n\t\trunLoggingCallbacks( "begin", {\n\t\t\ttotalTests: Test.count,\n\t\t\tmodules: modulesLog\n\t\t} );\n\t}\n\n\tconfig.blocking = false;\n\tprocess( true );\n}\n\nfunction process( last ) {\n\tfunction next() {\n\t\tprocess( last );\n\t}\n\tvar start = now();\n\tconfig.depth = ( config.depth || 0 ) + 1;\n\n\twhile ( config.queue.length && !config.blocking ) {\n\t\tif ( !defined.setTimeout || config.updateRate <= 0 ||\n\t\t\t\t( ( now() - start ) < config.updateRate ) ) {\n\t\t\tif ( config.current ) {\n\n\t\t\t\t// Reset async tracking for each phase of the Test lifecycle\n\t\t\t\tconfig.current.usedAsync = false;\n\t\t\t}\n\t\t\tconfig.queue.shift()();\n\t\t} else {\n\t\t\tsetTimeout( next, 13 );\n\t\t\tbreak;\n\t\t}\n\t}\n\tconfig.depth--;\n\tif ( last && !config.blocking && !config.queue.length && config.depth === 0 ) {\n\t\tdone();\n\t}\n}\n\nfunction pauseProcessing() {\n\tconfig.blocking = true;\n\n\tif ( config.testTimeout && defined.setTimeout ) {\n\t\tclearTimeout( config.timeout );\n\t\tconfig.timeout = setTimeout( function() {\n\t\t\tif ( config.current ) {\n\t\t\t\tconfig.current.semaphore = 0;\n\t\t\t\tQUnit.pushFailure( "Test timed out", sourceFromStacktrace( 2 ) );\n\t\t\t} else {\n\t\t\t\tthrow new Error( "Test timed out" );\n\t\t\t}\n\t\t\tresumeProcessing();\n\t\t}, config.testTimeout );\n\t}\n}\n\nfunction resumeProcessing() {\n\trunStarted = true;\n\n\t// A slight delay to allow this iteration of the event loop to finish (more assertions, etc.)\n\tif ( defined.setTimeout ) {\n\t\tsetTimeout( function() {\n\t\t\tif ( config.current && config.current.semaphore > 0 ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif ( config.timeout ) {\n\t\t\t\tclearTimeout( config.timeout );\n\t\t\t}\n\n\t\t\tbegin();\n\t\t}, 13 );\n\t} else {\n\t\tbegin();\n\t}\n}\n\nfunction done() {\n\tvar runtime, passed;\n\n\tconfig.autorun = true;\n\n\t// Log the last module results\n\tif ( config.previousModule ) {\n\t\trunLoggingCallbacks( "moduleDone", {\n\t\t\tname: config.previousModule.name,\n\t\t\ttests: config.previousModule.tests,\n\t\t\tfailed: config.moduleStats.bad,\n\t\t\tpassed: config.moduleStats.all - config.moduleStats.bad,\n\t\t\ttotal: config.moduleStats.all,\n\t\t\truntime: now() - config.moduleStats.started\n\t\t} );\n\t}\n\tdelete config.previousModule;\n\n\truntime = now() - config.started;\n\tpassed = config.stats.all - config.stats.bad;\n\n\trunLoggingCallbacks( "done", {\n\t\tfailed: config.stats.bad,\n\t\tpassed: passed,\n\t\ttotal: config.stats.all,\n\t\truntime: runtime\n\t} );\n}\n\nfunction setHook( module, hookName ) {\n\tif ( module.testEnvironment === undefined ) {\n\t\tmodule.testEnvironment = {};\n\t}\n\n\treturn function( callback ) {\n\t\tmodule.testEnvironment[ hookName ] = callback;\n\t};\n}\n\nvar focused = false;\nvar priorityCount = 0;\nvar unitSampler;\n\nfunction Test( settings ) {\n\tvar i, l;\n\n\t++Test.count;\n\n\textend( this, settings );\n\tthis.assertions = [];\n\tthis.semaphore = 0;\n\tthis.usedAsync = false;\n\tthis.module = config.currentModule;\n\tthis.stack = sourceFromStacktrace( 3 );\n\n\t// Register unique strings\n\tfor ( i = 0, l = this.module.tests; i < l.length; i++ ) {\n\t\tif ( this.module.tests[ i ].name === this.testName ) {\n\t\t\tthis.testName += " ";\n\t\t}\n\t}\n\n\tthis.testId = generateHash( this.module.name, this.testName );\n\n\tthis.module.tests.push( {\n\t\tname: this.testName,\n\t\ttestId: this.testId\n\t} );\n\n\tif ( settings.skip ) {\n\n\t\t// Skipped tests will fully ignore any sent callback\n\t\tthis.callback = function() {};\n\t\tthis.async = false;\n\t\tthis.expected = 0;\n\t} else {\n\t\tthis.assert = new Assert( this );\n\t}\n}\n\nTest.count = 0;\n\nTest.prototype = {\n\tbefore: function() {\n\t\tif (\n\n\t\t\t// Emit moduleStart when we\'re switching from one module to another\n\t\t\tthis.module !== config.previousModule ||\n\n\t\t\t\t// They could be equal (both undefined) but if the previousModule property doesn\'t\n\t\t\t\t// yet exist it means this is the first test in a suite that isn\'t wrapped in a\n\t\t\t\t// module, in which case we\'ll just emit a moduleStart event for \'undefined\'.\n\t\t\t\t// Without this, reporters can get testStart before moduleStart which is a problem.\n\t\t\t\t!hasOwn.call( config, "previousModule" )\n\t\t) {\n\t\t\tif ( hasOwn.call( config, "previousModule" ) ) {\n\t\t\t\trunLoggingCallbacks( "moduleDone", {\n\t\t\t\t\tname: config.previousModule.name,\n\t\t\t\t\ttests: config.previousModule.tests,\n\t\t\t\t\tfailed: config.moduleStats.bad,\n\t\t\t\t\tpassed: config.moduleStats.all - config.moduleStats.bad,\n\t\t\t\t\ttotal: config.moduleStats.all,\n\t\t\t\t\truntime: now() - config.moduleStats.started\n\t\t\t\t} );\n\t\t\t}\n\t\t\tconfig.previousModule = this.module;\n\t\t\tconfig.moduleStats = { all: 0, bad: 0, started: now() };\n\t\t\trunLoggingCallbacks( "moduleStart", {\n\t\t\t\tname: this.module.name,\n\t\t\t\ttests: this.module.tests\n\t\t\t} );\n\t\t}\n\n\t\tconfig.current = this;\n\n\t\tif ( this.module.testEnvironment ) {\n\t\t\tdelete this.module.testEnvironment.beforeEach;\n\t\t\tdelete this.module.testEnvironment.afterEach;\n\t\t}\n\t\tthis.testEnvironment = extend( {}, this.module.testEnvironment );\n\n\t\tthis.started = now();\n\t\trunLoggingCallbacks( "testStart", {\n\t\t\tname: this.testName,\n\t\t\tmodule: this.module.name,\n\t\t\ttestId: this.testId\n\t\t} );\n\n\t\tif ( !config.pollution ) {\n\t\t\tsaveGlobal();\n\t\t}\n\t},\n\n\trun: function() {\n\t\tvar promise;\n\n\t\tconfig.current = this;\n\n\t\tif ( this.async ) {\n\t\t\tQUnit.stop();\n\t\t}\n\n\t\tthis.callbackStarted = now();\n\n\t\tif ( config.notrycatch ) {\n\t\t\trunTest( this );\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\trunTest( this );\n\t\t} catch ( e ) {\n\t\t\tthis.pushFailure( "Died on test #" + ( this.assertions.length + 1 ) + " " +\n\t\t\t\tthis.stack + ": " + ( e.message || e ), extractStacktrace( e, 0 ) );\n\n\t\t\t// Else next test will carry the responsibility\n\t\t\tsaveGlobal();\n\n\t\t\t// Restart the tests if they\'re blocking\n\t\t\tif ( config.blocking ) {\n\t\t\t\tQUnit.start();\n\t\t\t}\n\t\t}\n\n\t\tfunction runTest( test ) {\n\t\t\tpromise = test.callback.call( test.testEnvironment, test.assert );\n\t\t\ttest.resolvePromise( promise );\n\t\t}\n\t},\n\n\tafter: function() {\n\t\tcheckPollution();\n\t},\n\n\tqueueHook: function( hook, hookName ) {\n\t\tvar promise,\n\t\t\ttest = this;\n\t\treturn function runHook() {\n\t\t\tconfig.current = test;\n\t\t\tif ( config.notrycatch ) {\n\t\t\t\tcallHook();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tcallHook();\n\t\t\t} catch ( error ) {\n\t\t\t\ttest.pushFailure( hookName + " failed on " + test.testName + ": " +\n\t\t\t\t( error.message || error ), extractStacktrace( error, 0 ) );\n\t\t\t}\n\n\t\t\tfunction callHook() {\n\t\t\t\tpromise = hook.call( test.testEnvironment, test.assert );\n\t\t\t\ttest.resolvePromise( promise, hookName );\n\t\t\t}\n\t\t};\n\t},\n\n\t// Currently only used for module level hooks, can be used to add global level ones\n\thooks: function( handler ) {\n\t\tvar hooks = [];\n\n\t\tfunction processHooks( test, module ) {\n\t\t\tif ( module.parentModule ) {\n\t\t\t\tprocessHooks( test, module.parentModule );\n\t\t\t}\n\t\t\tif ( module.testEnvironment &&\n\t\t\t\tQUnit.objectType( module.testEnvironment[ handler ] ) === "function" ) {\n\t\t\t\thooks.push( test.queueHook( module.testEnvironment[ handler ], handler ) );\n\t\t\t}\n\t\t}\n\n\t\t// Hooks are ignored on skipped tests\n\t\tif ( !this.skip ) {\n\t\t\tprocessHooks( this, this.module );\n\t\t}\n\t\treturn hooks;\n\t},\n\n\tfinish: function() {\n\t\tconfig.current = this;\n\t\tif ( config.requireExpects && this.expected === null ) {\n\t\t\tthis.pushFailure( "Expected number of assertions to be defined, but expect() was " +\n\t\t\t\t"not called.", this.stack );\n\t\t} else if ( this.expected !== null && this.expected !== this.assertions.length ) {\n\t\t\tthis.pushFailure( "Expected " + this.expected + " assertions, but " +\n\t\t\t\tthis.assertions.length + " were run", this.stack );\n\t\t} else if ( this.expected === null && !this.assertions.length ) {\n\t\t\tthis.pushFailure( "Expected at least one assertion, but none were run - call " +\n\t\t\t\t"expect(0) to accept zero assertions.", this.stack );\n\t\t}\n\n\t\tvar i,\n\t\t\tbad = 0;\n\n\t\tthis.runtime = now() - this.started;\n\t\tconfig.stats.all += this.assertions.length;\n\t\tconfig.moduleStats.all += this.assertions.length;\n\n\t\tfor ( i = 0; i < this.assertions.length; i++ ) {\n\t\t\tif ( !this.assertions[ i ].result ) {\n\t\t\t\tbad++;\n\t\t\t\tconfig.stats.bad++;\n\t\t\t\tconfig.moduleStats.bad++;\n\t\t\t}\n\t\t}\n\n\t\trunLoggingCallbacks( "testDone", {\n\t\t\tname: this.testName,\n\t\t\tmodule: this.module.name,\n\t\t\tskipped: !!this.skip,\n\t\t\tfailed: bad,\n\t\t\tpassed: this.assertions.length - bad,\n\t\t\ttotal: this.assertions.length,\n\t\t\truntime: this.runtime,\n\n\t\t\t// HTML Reporter use\n\t\t\tassertions: this.assertions,\n\t\t\ttestId: this.testId,\n\n\t\t\t// Source of Test\n\t\t\tsource: this.stack,\n\n\t\t\t// DEPRECATED: this property will be removed in 2.0.0, use runtime instead\n\t\t\tduration: this.runtime\n\t\t} );\n\n\t\t// QUnit.reset() is deprecated and will be replaced for a new\n\t\t// fixture reset function on QUnit 2.0/2.1.\n\t\t// It\'s still called here for backwards compatibility handling\n\t\tQUnit.reset();\n\n\t\tconfig.current = undefined;\n\t},\n\n\tqueue: function() {\n\t\tvar priority,\n\t\t\ttest = this;\n\n\t\tif ( !this.valid() ) {\n\t\t\treturn;\n\t\t}\n\n\t\tfunction run() {\n\n\t\t\t// Each of these can by async\n\t\t\tsynchronize( [\n\t\t\t\tfunction() {\n\t\t\t\t\ttest.before();\n\t\t\t\t},\n\n\t\t\t\ttest.hooks( "beforeEach" ),\n\t\t\t\tfunction() {\n\t\t\t\t\ttest.run();\n\t\t\t\t},\n\n\t\t\t\ttest.hooks( "afterEach" ).reverse(),\n\n\t\t\t\tfunction() {\n\t\t\t\t\ttest.after();\n\t\t\t\t},\n\t\t\t\tfunction() {\n\t\t\t\t\ttest.finish();\n\t\t\t\t}\n\t\t\t] );\n\t\t}\n\n\t\t// Prioritize previously failed tests, detected from sessionStorage\n\t\tpriority = QUnit.config.reorder && defined.sessionStorage &&\n\t\t\t\t+sessionStorage.getItem( "qunit-test-" + this.module.name + "-" + this.testName );\n\n\t\treturn synchronize( run, priority, config.seed );\n\t},\n\n\tpushResult: function( resultInfo ) {\n\n\t\t// Destructure of resultInfo = { result, actual, expected, message, negative }\n\t\tvar source,\n\t\t\tdetails = {\n\t\t\t\tmodule: this.module.name,\n\t\t\t\tname: this.testName,\n\t\t\t\tresult: resultInfo.result,\n\t\t\t\tmessage: resultInfo.message,\n\t\t\t\tactual: resultInfo.actual,\n\t\t\t\texpected: resultInfo.expected,\n\t\t\t\ttestId: this.testId,\n\t\t\t\tnegative: resultInfo.negative || false,\n\t\t\t\truntime: now() - this.started\n\t\t\t};\n\n\t\tif ( !resultInfo.result ) {\n\t\t\tsource = sourceFromStacktrace();\n\n\t\t\tif ( source ) {\n\t\t\t\tdetails.source = source;\n\t\t\t}\n\t\t}\n\n\t\trunLoggingCallbacks( "log", details );\n\n\t\tthis.assertions.push( {\n\t\t\tresult: !!resultInfo.result,\n\t\t\tmessage: resultInfo.message\n\t\t} );\n\t},\n\n\tpushFailure: function( message, source, actual ) {\n\t\tif ( !( this instanceof Test ) ) {\n\t\t\tthrow new Error( "pushFailure() assertion outside test context, was " +\n\t\t\t\tsourceFromStacktrace( 2 ) );\n\t\t}\n\n\t\tvar details = {\n\t\t\t\tmodule: this.module.name,\n\t\t\t\tname: this.testName,\n\t\t\t\tresult: false,\n\t\t\t\tmessage: message || "error",\n\t\t\t\tactual: actual || null,\n\t\t\t\ttestId: this.testId,\n\t\t\t\truntime: now() - this.started\n\t\t\t};\n\n\t\tif ( source ) {\n\t\t\tdetails.source = source;\n\t\t}\n\n\t\trunLoggingCallbacks( "log", details );\n\n\t\tthis.assertions.push( {\n\t\t\tresult: false,\n\t\t\tmessage: message\n\t\t} );\n\t},\n\n\tresolvePromise: function( promise, phase ) {\n\t\tvar then, message,\n\t\t\ttest = this;\n\t\tif ( promise != null ) {\n\t\t\tthen = promise.then;\n\t\t\tif ( QUnit.objectType( then ) === "function" ) {\n\t\t\t\tQUnit.stop();\n\t\t\t\tthen.call(\n\t\t\t\t\tpromise,\n\t\t\t\t\tfunction() { QUnit.start(); },\n\t\t\t\t\tfunction( error ) {\n\t\t\t\t\t\tmessage = "Promise rejected " +\n\t\t\t\t\t\t\t( !phase ? "during" : phase.replace( /Each$/, "" ) ) +\n\t\t\t\t\t\t\t" " + test.testName + ": " + ( error.message || error );\n\t\t\t\t\t\ttest.pushFailure( message, extractStacktrace( error, 0 ) );\n\n\t\t\t\t\t\t// Else next test will carry the responsibility\n\t\t\t\t\t\tsaveGlobal();\n\n\t\t\t\t\t\t// Unblock\n\t\t\t\t\t\tQUnit.start();\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t},\n\n\tvalid: function() {\n\t\tvar filter = config.filter,\n\t\t\tregexFilter = /^(!?)\\/([\\w\\W]*)\\/(i?$)/.exec( filter ),\n\t\t\tmodule = config.module && config.module.toLowerCase(),\n\t\t\tfullName = ( this.module.name + ": " + this.testName );\n\n\t\tfunction moduleChainNameMatch( testModule ) {\n\t\t\tvar testModuleName = testModule.name ? testModule.name.toLowerCase() : null;\n\t\t\tif ( testModuleName === module ) {\n\t\t\t\treturn true;\n\t\t\t} else if ( testModule.parentModule ) {\n\t\t\t\treturn moduleChainNameMatch( testModule.parentModule );\n\t\t\t} else {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tfunction moduleChainIdMatch( testModule ) {\n\t\t\treturn inArray( testModule.moduleId, config.moduleId ) > -1 ||\n\t\t\t\ttestModule.parentModule && moduleChainIdMatch( testModule.parentModule );\n\t\t}\n\n\t\t// Internally-generated tests are always valid\n\t\tif ( this.callback && this.callback.validTest ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif ( config.moduleId && config.moduleId.length > 0 &&\n\t\t\t!moduleChainIdMatch( this.module ) ) {\n\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( config.testId && config.testId.length > 0 &&\n\t\t\tinArray( this.testId, config.testId ) < 0 ) {\n\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( module && !moduleChainNameMatch( this.module ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( !filter ) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn regexFilter ?\n\t\t\tthis.regexFilter( !!regexFilter[ 1 ], regexFilter[ 2 ], regexFilter[ 3 ], fullName ) :\n\t\t\tthis.stringFilter( filter, fullName );\n\t},\n\n\tregexFilter: function( exclude, pattern, flags, fullName ) {\n\t\tvar regex = new RegExp( pattern, flags );\n\t\tvar match = regex.test( fullName );\n\n\t\treturn match !== exclude;\n\t},\n\n\tstringFilter: function( filter, fullName ) {\n\t\tfilter = filter.toLowerCase();\n\t\tfullName = fullName.toLowerCase();\n\n\t\tvar include = filter.charAt( 0 ) !== "!";\n\t\tif ( !include ) {\n\t\t\tfilter = filter.slice( 1 );\n\t\t}\n\n\t\t// If the filter matches, we need to honour include\n\t\tif ( fullName.indexOf( filter ) !== -1 ) {\n\t\t\treturn include;\n\t\t}\n\n\t\t// Otherwise, do the opposite\n\t\treturn !include;\n\t}\n};\n\n// Resets the test setup. Useful for tests that modify the DOM.\n/*\nDEPRECATED: Use multiple tests instead of resetting inside a test.\nUse testStart or testDone for custom cleanup.\nThis method will throw an error in 2.0, and will be removed in 2.1\n*/\nQUnit.reset = function() {\n\n\t// Return on non-browser environments\n\t// This is necessary to not break on node tests\n\tif ( !defined.document ) {\n\t\treturn;\n\t}\n\n\tvar fixture = defined.document && document.getElementById &&\n\t\t\tdocument.getElementById( "qunit-fixture" );\n\n\tif ( fixture ) {\n\t\tfixture.innerHTML = config.fixture;\n\t}\n};\n\nQUnit.pushFailure = function() {\n\tif ( !QUnit.config.current ) {\n\t\tthrow new Error( "pushFailure() assertion outside test context, in " +\n\t\t\tsourceFromStacktrace( 2 ) );\n\t}\n\n\t// Gets current test obj\n\tvar currentTest = QUnit.config.current;\n\n\treturn currentTest.pushFailure.apply( currentTest, arguments );\n};\n\n// Based on Java\'s String.hashCode, a simple but not\n// rigorously collision resistant hashing function\nfunction generateHash( module, testName ) {\n\tvar hex,\n\t\ti = 0,\n\t\thash = 0,\n\t\tstr = module + "\\x1C" + testName,\n\t\tlen = str.length;\n\n\tfor ( ; i < len; i++ ) {\n\t\thash = ( ( hash << 5 ) - hash ) + str.charCodeAt( i );\n\t\thash |= 0;\n\t}\n\n\t// Convert the possibly negative integer hash code into an 8 character hex string, which isn\'t\n\t// strictly necessary but increases user understanding that the id is a SHA-like hash\n\thex = ( 0x100000000 + hash ).toString( 16 );\n\tif ( hex.length < 8 ) {\n\t\thex = "0000000" + hex;\n\t}\n\n\treturn hex.slice( -8 );\n}\n\nfunction synchronize( callback, priority, seed ) {\n\tvar last = !priority,\n\t\tindex;\n\n\tif ( QUnit.objectType( callback ) === "array" ) {\n\t\twhile ( callback.length ) {\n\t\t\tsynchronize( callback.shift() );\n\t\t}\n\t\treturn;\n\t}\n\n\tif ( priority ) {\n\t\tconfig.queue.splice( priorityCount++, 0, callback );\n\t} else if ( seed ) {\n\t\tif ( !unitSampler ) {\n\t\t\tunitSampler = unitSamplerGenerator( seed );\n\t\t}\n\n\t\t// Insert into a random position after all priority items\n\t\tindex = Math.floor( unitSampler() * ( config.queue.length - priorityCount + 1 ) );\n\t\tconfig.queue.splice( priorityCount + index, 0, callback );\n\t} else {\n\t\tconfig.queue.push( callback );\n\t}\n\n\tif ( config.autorun && !config.blocking ) {\n\t\tprocess( last );\n\t}\n}\n\nfunction unitSamplerGenerator( seed ) {\n\n\t// 32-bit xorshift, requires only a nonzero seed\n\t// http://excamera.com/sphinx/article-xorshift.html\n\tvar sample = parseInt( generateHash( seed ), 16 ) || -1;\n\treturn function() {\n\t\tsample ^= sample << 13;\n\t\tsample ^= sample >>> 17;\n\t\tsample ^= sample << 5;\n\n\t\t// ECMAScript has no unsigned number type\n\t\tif ( sample < 0 ) {\n\t\t\tsample += 0x100000000;\n\t\t}\n\n\t\treturn sample / 0x100000000;\n\t};\n}\n\nfunction saveGlobal() {\n\tconfig.pollution = [];\n\n\tif ( config.noglobals ) {\n\t\tfor ( var key in global ) {\n\t\t\tif ( hasOwn.call( global, key ) ) {\n\n\t\t\t\t// In Opera sometimes DOM element ids show up here, ignore them\n\t\t\t\tif ( /^qunit-test-output/.test( key ) ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconfig.pollution.push( key );\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction checkPollution() {\n\tvar newGlobals,\n\t\tdeletedGlobals,\n\t\told = config.pollution;\n\n\tsaveGlobal();\n\n\tnewGlobals = diff( config.pollution, old );\n\tif ( newGlobals.length > 0 ) {\n\t\tQUnit.pushFailure( "Introduced global variable(s): " + newGlobals.join( ", " ) );\n\t}\n\n\tdeletedGlobals = diff( old, config.pollution );\n\tif ( deletedGlobals.length > 0 ) {\n\t\tQUnit.pushFailure( "Deleted global variable(s): " + deletedGlobals.join( ", " ) );\n\t}\n}\n\n// Will be exposed as QUnit.asyncTest\nfunction asyncTest( testName, expected, callback ) {\n\tif ( arguments.length === 2 ) {\n\t\tcallback = expected;\n\t\texpected = null;\n\t}\n\n\tQUnit.test( testName, expected, callback, true );\n}\n\n// Will be exposed as QUnit.test\nfunction test( testName, expected, callback, async ) {\n\tif ( focused ) { return; }\n\n\tvar newTest;\n\n\tif ( arguments.length === 2 ) {\n\t\tcallback = expected;\n\t\texpected = null;\n\t}\n\n\tnewTest = new Test( {\n\t\ttestName: testName,\n\t\texpected: expected,\n\t\tasync: async,\n\t\tcallback: callback\n\t} );\n\n\tnewTest.queue();\n}\n\n// Will be exposed as QUnit.skip\nfunction skip( testName ) {\n\tif ( focused ) { return; }\n\n\tvar test = new Test( {\n\t\ttestName: testName,\n\t\tskip: true\n\t} );\n\n\ttest.queue();\n}\n\n// Will be exposed as QUnit.only\nfunction only( testName, expected, callback, async ) {\n\tvar newTest;\n\n\tif ( focused ) { return; }\n\n\tQUnit.config.queue.length = 0;\n\tfocused = true;\n\n\tif ( arguments.length === 2 ) {\n\t\tcallback = expected;\n\t\texpected = null;\n\t}\n\n\tnewTest = new Test( {\n\t\ttestName: testName,\n\t\texpected: expected,\n\t\tasync: async,\n\t\tcallback: callback\n\t} );\n\n\tnewTest.queue();\n}\n\nfunction Assert( testContext ) {\n\tthis.test = testContext;\n}\n\n// Assert helpers\nQUnit.assert = Assert.prototype = {\n\n\t// Specify the number of expected assertions to guarantee that failed test\n\t// (no assertions are run at all) don\'t slip through.\n\texpect: function( asserts ) {\n\t\tif ( arguments.length === 1 ) {\n\t\t\tthis.test.expected = asserts;\n\t\t} else {\n\t\t\treturn this.test.expected;\n\t\t}\n\t},\n\n\t// Increment this Test\'s semaphore counter, then return a function that\n\t// decrements that counter a maximum of once.\n\tasync: function( count ) {\n\t\tvar test = this.test,\n\t\t\tpopped = false,\n\t\t\tacceptCallCount = count;\n\n\t\tif ( typeof acceptCallCount === "undefined" ) {\n\t\t\tacceptCallCount = 1;\n\t\t}\n\n\t\ttest.semaphore += 1;\n\t\ttest.usedAsync = true;\n\t\tpauseProcessing();\n\n\t\treturn function done() {\n\n\t\t\tif ( popped ) {\n\t\t\t\ttest.pushFailure( "Too many calls to the `assert.async` callback",\n\t\t\t\t\tsourceFromStacktrace( 2 ) );\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tacceptCallCount -= 1;\n\t\t\tif ( acceptCallCount > 0 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\ttest.semaphore -= 1;\n\t\t\tpopped = true;\n\t\t\tresumeProcessing();\n\t\t};\n\t},\n\n\t// Exports test.push() to the user API\n\t// Alias of pushResult.\n\tpush: function( result, actual, expected, message, negative ) {\n\t\tvar currentAssert = this instanceof Assert ? this : QUnit.config.current.assert;\n\t\treturn currentAssert.pushResult( {\n\t\t\tresult: result,\n\t\t\tactual: actual,\n\t\t\texpected: expected,\n\t\t\tmessage: message,\n\t\t\tnegative: negative\n\t\t} );\n\t},\n\n\tpushResult: function( resultInfo ) {\n\n\t\t// Destructure of resultInfo = { result, actual, expected, message, negative }\n\t\tvar assert = this,\n\t\t\tcurrentTest = ( assert instanceof Assert && assert.test ) || QUnit.config.current;\n\n\t\t// Backwards compatibility fix.\n\t\t// Allows the direct use of global exported assertions and QUnit.assert.*\n\t\t// Although, it\'s use is not recommended as it can leak assertions\n\t\t// to other tests from async tests, because we only get a reference to the current test,\n\t\t// not exactly the test where assertion were intended to be called.\n\t\tif ( !currentTest ) {\n\t\t\tthrow new Error( "assertion outside test context, in " + sourceFromStacktrace( 2 ) );\n\t\t}\n\n\t\tif ( currentTest.usedAsync === true && currentTest.semaphore === 0 ) {\n\t\t\tcurrentTest.pushFailure( "Assertion after the final `assert.async` was resolved",\n\t\t\t\tsourceFromStacktrace( 2 ) );\n\n\t\t\t// Allow this assertion to continue running anyway...\n\t\t}\n\n\t\tif ( !( assert instanceof Assert ) ) {\n\t\t\tassert = currentTest.assert;\n\t\t}\n\n\t\treturn assert.test.pushResult( resultInfo );\n\t},\n\n\tok: function( result, message ) {\n\t\tmessage = message || ( result ? "okay" : "failed, expected argument to be truthy, was: " +\n\t\t\tQUnit.dump.parse( result ) );\n\t\tthis.pushResult( {\n\t\t\tresult: !!result,\n\t\t\tactual: result,\n\t\t\texpected: true,\n\t\t\tmessage: message\n\t\t} );\n\t},\n\n\tnotOk: function( result, message ) {\n\t\tmessage = message || ( !result ? "okay" : "failed, expected argument to be falsy, was: " +\n\t\t\tQUnit.dump.parse( result ) );\n\t\tthis.pushResult( {\n\t\t\tresult: !result,\n\t\t\tactual: result,\n\t\t\texpected: false,\n\t\t\tmessage: message\n\t\t} );\n\t},\n\n\tequal: function( actual, expected, message ) {\n\t\t/*jshint eqeqeq:false */\n\t\tthis.pushResult( {\n\t\t\tresult: expected == actual,\n\t\t\tactual: actual,\n\t\t\texpected: expected,\n\t\t\tmessage: message\n\t\t} );\n\t},\n\n\tnotEqual: function( actual, expected, message ) {\n\t\t/*jshint eqeqeq:false */\n\t\tthis.pushResult( {\n\t\t\tresult: expected != actual,\n\t\t\tactual: actual,\n\t\t\texpected: expected,\n\t\t\tmessage: message,\n\t\t\tnegative: true\n\t\t} );\n\t},\n\n\tpropEqual: function( actual, expected, message ) {\n\t\tactual = objectValues( actual );\n\t\texpected = objectValues( expected );\n\t\tthis.pushResult( {\n\t\t\tresult: QUnit.equiv( actual, expected ),\n\t\t\tactual: actual,\n\t\t\texpected: expected,\n\t\t\tmessage: message\n\t\t} );\n\t},\n\n\tnotPropEqual: function( actual, expected, message ) {\n\t\tactual = objectValues( actual );\n\t\texpected = objectValues( expected );\n\t\tthis.pushResult( {\n\t\t\tresult: !QUnit.equiv( actual, expected ),\n\t\t\tactual: actual,\n\t\t\texpected: expected,\n\t\t\tmessage: message,\n\t\t\tnegative: true\n\t\t} );\n\t},\n\n\tdeepEqual: function( actual, expected, message ) {\n\t\tthis.pushResult( {\n\t\t\tresult: QUnit.equiv( actual, expected ),\n\t\t\tactual: actual,\n\t\t\texpected: expected,\n\t\t\tmessage: message\n\t\t} );\n\t},\n\n\tnotDeepEqual: function( actual, expected, message ) {\n\t\tthis.pushResult( {\n\t\t\tresult: !QUnit.equiv( actual, expected ),\n\t\t\tactual: actual,\n\t\t\texpected: expected,\n\t\t\tmessage: message,\n\t\t\tnegative: true\n\t\t} );\n\t},\n\n\tstrictEqual: function( actual, expected, message ) {\n\t\tthis.pushResult( {\n\t\t\tresult: expected === actual,\n\t\t\tactual: actual,\n\t\t\texpected: expected,\n\t\t\tmessage: message\n\t\t} );\n\t},\n\n\tnotStrictEqual: function( actual, expected, message ) {\n\t\tthis.pushResult( {\n\t\t\tresult: expected !== actual,\n\t\t\tactual: actual,\n\t\t\texpected: expected,\n\t\t\tmessage: message,\n\t\t\tnegative: true\n\t\t} );\n\t},\n\n\t"throws": function( block, expected, message ) {\n\t\tvar actual, expectedType,\n\t\t\texpectedOutput = expected,\n\t\t\tok = false,\n\t\t\tcurrentTest = ( this instanceof Assert && this.test ) || QUnit.config.current;\n\n\t\t// \'expected\' is optional unless doing string comparison\n\t\tif ( message == null && typeof expected === "string" ) {\n\t\t\tmessage = expected;\n\t\t\texpected = null;\n\t\t}\n\n\t\tcurrentTest.ignoreGlobalErrors = true;\n\t\ttry {\n\t\t\tblock.call( currentTest.testEnvironment );\n\t\t} catch ( e ) {\n\t\t\tactual = e;\n\t\t}\n\t\tcurrentTest.ignoreGlobalErrors = false;\n\n\t\tif ( actual ) {\n\t\t\texpectedType = QUnit.objectType( expected );\n\n\t\t\t// We don\'t want to validate thrown error\n\t\t\tif ( !expected ) {\n\t\t\t\tok = true;\n\t\t\t\texpectedOutput = null;\n\n\t\t\t// Expected is a regexp\n\t\t\t} else if ( expectedType === "regexp" ) {\n\t\t\t\tok = expected.test( errorString( actual ) );\n\n\t\t\t// Expected is a string\n\t\t\t} else if ( expectedType === "string" ) {\n\t\t\t\tok = expected === errorString( actual );\n\n\t\t\t// Expected is a constructor, maybe an Error constructor\n\t\t\t} else if ( expectedType === "function" && actual instanceof expected ) {\n\t\t\t\tok = true;\n\n\t\t\t// Expected is an Error object\n\t\t\t} else if ( expectedType === "object" ) {\n\t\t\t\tok = actual instanceof expected.constructor &&\n\t\t\t\t\tactual.name === expected.name &&\n\t\t\t\t\tactual.message === expected.message;\n\n\t\t\t// Expected is a validation function which returns true if validation passed\n\t\t\t} else if ( expectedType === "function" && expected.call( {}, actual ) === true ) {\n\t\t\t\texpectedOutput = null;\n\t\t\t\tok = true;\n\t\t\t}\n\t\t}\n\n\t\tcurrentTest.assert.pushResult( {\n\t\t\tresult: ok,\n\t\t\tactual: actual,\n\t\t\texpected: expectedOutput,\n\t\t\tmessage: message\n\t\t} );\n\t}\n};\n\n// Provide an alternative to assert.throws(), for environments that consider throws a reserved word\n// Known to us are: Closure Compiler, Narwhal\n( function() {\n\t/*jshint sub:true */\n\tAssert.prototype.raises = Assert.prototype [ "throws" ]; //jscs:ignore requireDotNotation\n}() );\n\nfunction errorString( error ) {\n\tvar name, message,\n\t\tresultErrorString = error.toString();\n\tif ( resultErrorString.substring( 0, 7 ) === "[object" ) {\n\t\tname = error.name ? error.name.toString() : "Error";\n\t\tmessage = error.message ? error.message.toString() : "";\n\t\tif ( name && message ) {\n\t\t\treturn name + ": " + message;\n\t\t} else if ( name ) {\n\t\t\treturn name;\n\t\t} else if ( message ) {\n\t\t\treturn message;\n\t\t} else {\n\t\t\treturn "Error";\n\t\t}\n\t} else {\n\t\treturn resultErrorString;\n\t}\n}\n\n// Test for equality any JavaScript type.\n// Author: Philippe Rathé \nQUnit.equiv = ( function() {\n\n\t// Stack to decide between skip/abort functions\n\tvar callers = [];\n\n\t// Stack to avoiding loops from circular referencing\n\tvar parents = [];\n\tvar parentsB = [];\n\n\tvar getProto = Object.getPrototypeOf || function( obj ) {\n\n\t\t/*jshint proto: true */\n\t\treturn obj.__proto__;\n\t};\n\n\tfunction useStrictEquality( b, a ) {\n\n\t\t// To catch short annotation VS \'new\' annotation of a declaration. e.g.:\n\t\t// `var i = 1;`\n\t\t// `var j = new Number(1);`\n\t\tif ( typeof a === "object" ) {\n\t\t\ta = a.valueOf();\n\t\t}\n\t\tif ( typeof b === "object" ) {\n\t\t\tb = b.valueOf();\n\t\t}\n\n\t\treturn a === b;\n\t}\n\n\tfunction compareConstructors( a, b ) {\n\t\tvar protoA = getProto( a );\n\t\tvar protoB = getProto( b );\n\n\t\t// Comparing constructors is more strict than using `instanceof`\n\t\tif ( a.constructor === b.constructor ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Ref #851\n\t\t// If the obj prototype descends from a null constructor, treat it\n\t\t// as a null prototype.\n\t\tif ( protoA && protoA.constructor === null ) {\n\t\t\tprotoA = null;\n\t\t}\n\t\tif ( protoB && protoB.constructor === null ) {\n\t\t\tprotoB = null;\n\t\t}\n\n\t\t// Allow objects with no prototype to be equivalent to\n\t\t// objects with Object as their constructor.\n\t\tif ( ( protoA === null && protoB === Object.prototype ) ||\n\t\t\t\t( protoB === null && protoA === Object.prototype ) ) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tfunction getRegExpFlags( regexp ) {\n\t\treturn "flags" in regexp ? regexp.flags : regexp.toString().match( /[gimuy]*$/ )[ 0 ];\n\t}\n\n\tvar callbacks = {\n\t\t"string": useStrictEquality,\n\t\t"boolean": useStrictEquality,\n\t\t"number": useStrictEquality,\n\t\t"null": useStrictEquality,\n\t\t"undefined": useStrictEquality,\n\t\t"symbol": useStrictEquality,\n\t\t"date": useStrictEquality,\n\n\t\t"nan": function() {\n\t\t\treturn true;\n\t\t},\n\n\t\t"regexp": function( b, a ) {\n\t\t\treturn a.source === b.source &&\n\n\t\t\t\t// Include flags in the comparison\n\t\t\t\tgetRegExpFlags( a ) === getRegExpFlags( b );\n\t\t},\n\n\t\t// - skip when the property is a method of an instance (OOP)\n\t\t// - abort otherwise,\n\t\t// initial === would have catch identical references anyway\n\t\t"function": function() {\n\t\t\tvar caller = callers[ callers.length - 1 ];\n\t\t\treturn caller !== Object && typeof caller !== "undefined";\n\t\t},\n\n\t\t"array": function( b, a ) {\n\t\t\tvar i, j, len, loop, aCircular, bCircular;\n\n\t\t\tlen = a.length;\n\t\t\tif ( len !== b.length ) {\n\n\t\t\t\t// Safe and faster\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Track reference to avoid circular references\n\t\t\tparents.push( a );\n\t\t\tparentsB.push( b );\n\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\tloop = false;\n\t\t\t\tfor ( j = 0; j < parents.length; j++ ) {\n\t\t\t\t\taCircular = parents[ j ] === a[ i ];\n\t\t\t\t\tbCircular = parentsB[ j ] === b[ i ];\n\t\t\t\t\tif ( aCircular || bCircular ) {\n\t\t\t\t\t\tif ( a[ i ] === b[ i ] || aCircular && bCircular ) {\n\t\t\t\t\t\t\tloop = true;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tparents.pop();\n\t\t\t\t\t\t\tparentsB.pop();\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif ( !loop && !innerEquiv( a[ i ], b[ i ] ) ) {\n\t\t\t\t\tparents.pop();\n\t\t\t\t\tparentsB.pop();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tparents.pop();\n\t\t\tparentsB.pop();\n\t\t\treturn true;\n\t\t},\n\n\t\t"set": function( b, a ) {\n\t\t\tvar innerEq,\n\t\t\t\touterEq = true;\n\n\t\t\tif ( a.size !== b.size ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\ta.forEach( function( aVal ) {\n\t\t\t\tinnerEq = false;\n\n\t\t\t\tb.forEach( function( bVal ) {\n\t\t\t\t\tif ( innerEquiv( bVal, aVal ) ) {\n\t\t\t\t\t\tinnerEq = true;\n\t\t\t\t\t}\n\t\t\t\t} );\n\n\t\t\t\tif ( !innerEq ) {\n\t\t\t\t\touterEq = false;\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\treturn outerEq;\n\t\t},\n\n\t\t"map": function( b, a ) {\n\t\t\tvar innerEq,\n\t\t\t\touterEq = true;\n\n\t\t\tif ( a.size !== b.size ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\ta.forEach( function( aVal, aKey ) {\n\t\t\t\tinnerEq = false;\n\n\t\t\t\tb.forEach( function( bVal, bKey ) {\n\t\t\t\t\tif ( innerEquiv( [ bVal, bKey ], [ aVal, aKey ] ) ) {\n\t\t\t\t\t\tinnerEq = true;\n\t\t\t\t\t}\n\t\t\t\t} );\n\n\t\t\t\tif ( !innerEq ) {\n\t\t\t\t\touterEq = false;\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\treturn outerEq;\n\t\t},\n\n\t\t"object": function( b, a ) {\n\t\t\tvar i, j, loop, aCircular, bCircular;\n\n\t\t\t// Default to true\n\t\t\tvar eq = true;\n\t\t\tvar aProperties = [];\n\t\t\tvar bProperties = [];\n\n\t\t\tif ( compareConstructors( a, b ) === false ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Stack constructor before traversing properties\n\t\t\tcallers.push( a.constructor );\n\n\t\t\t// Track reference to avoid circular references\n\t\t\tparents.push( a );\n\t\t\tparentsB.push( b );\n\n\t\t\t// Be strict: don\'t ensure hasOwnProperty and go deep\n\t\t\tfor ( i in a ) {\n\t\t\t\tloop = false;\n\t\t\t\tfor ( j = 0; j < parents.length; j++ ) {\n\t\t\t\t\taCircular = parents[ j ] === a[ i ];\n\t\t\t\t\tbCircular = parentsB[ j ] === b[ i ];\n\t\t\t\t\tif ( aCircular || bCircular ) {\n\t\t\t\t\t\tif ( a[ i ] === b[ i ] || aCircular && bCircular ) {\n\t\t\t\t\t\t\tloop = true;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\teq = false;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\taProperties.push( i );\n\t\t\t\tif ( !loop && !innerEquiv( a[ i ], b[ i ] ) ) {\n\t\t\t\t\teq = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tparents.pop();\n\t\t\tparentsB.pop();\n\n\t\t\t// Unstack, we are done\n\t\t\tcallers.pop();\n\n\t\t\tfor ( i in b ) {\n\n\t\t\t\t// Collect b\'s properties\n\t\t\t\tbProperties.push( i );\n\t\t\t}\n\n\t\t\t// Ensures identical properties name\n\t\t\treturn eq && innerEquiv( aProperties.sort(), bProperties.sort() );\n\t\t}\n\t};\n\n\tfunction typeEquiv( a, b ) {\n\t\tvar type = QUnit.objectType( a );\n\t\treturn QUnit.objectType( b ) === type && callbacks[ type ]( b, a );\n\t}\n\n\t// The real equiv function\n\tfunction innerEquiv( a, b ) {\n\n\t\t// We\'re done when there\'s nothing more to compare\n\t\tif ( arguments.length < 2 ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Require type-specific equality\n\t\treturn ( a === b || typeEquiv( a, b ) ) &&\n\n\t\t\t// ...across all consecutive argument pairs\n\t\t\t( arguments.length === 2 || innerEquiv.apply( this, [].slice.call( arguments, 1 ) ) );\n\t}\n\n\treturn innerEquiv;\n}() );\n\n// Based on jsDump by Ariel Flesler\n// http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html\nQUnit.dump = ( function() {\n\tfunction quote( str ) {\n\t\treturn "\\"" + str.toString().replace( /\\\\/g, "\\\\\\\\" ).replace( /"/g, "\\\\\\"" ) + "\\"";\n\t}\n\tfunction literal( o ) {\n\t\treturn o + "";\n\t}\n\tfunction join( pre, arr, post ) {\n\t\tvar s = dump.separator(),\n\t\t\tbase = dump.indent(),\n\t\t\tinner = dump.indent( 1 );\n\t\tif ( arr.join ) {\n\t\t\tarr = arr.join( "," + s + inner );\n\t\t}\n\t\tif ( !arr ) {\n\t\t\treturn pre + post;\n\t\t}\n\t\treturn [ pre, inner + arr, base + post ].join( s );\n\t}\n\tfunction array( arr, stack ) {\n\t\tvar i = arr.length,\n\t\t\tret = new Array( i );\n\n\t\tif ( dump.maxDepth && dump.depth > dump.maxDepth ) {\n\t\t\treturn "[object Array]";\n\t\t}\n\n\t\tthis.up();\n\t\twhile ( i-- ) {\n\t\t\tret[ i ] = this.parse( arr[ i ], undefined, stack );\n\t\t}\n\t\tthis.down();\n\t\treturn join( "[", ret, "]" );\n\t}\n\n\tvar reName = /^function (\\w+)/,\n\t\tdump = {\n\n\t\t\t// The objType is used mostly internally, you can fix a (custom) type in advance\n\t\t\tparse: function( obj, objType, stack ) {\n\t\t\t\tstack = stack || [];\n\t\t\t\tvar res, parser, parserType,\n\t\t\t\t\tinStack = inArray( obj, stack );\n\n\t\t\t\tif ( inStack !== -1 ) {\n\t\t\t\t\treturn "recursion(" + ( inStack - stack.length ) + ")";\n\t\t\t\t}\n\n\t\t\t\tobjType = objType || this.typeOf( obj );\n\t\t\t\tparser = this.parsers[ objType ];\n\t\t\t\tparserType = typeof parser;\n\n\t\t\t\tif ( parserType === "function" ) {\n\t\t\t\t\tstack.push( obj );\n\t\t\t\t\tres = parser.call( this, obj, stack );\n\t\t\t\t\tstack.pop();\n\t\t\t\t\treturn res;\n\t\t\t\t}\n\t\t\t\treturn ( parserType === "string" ) ? parser : this.parsers.error;\n\t\t\t},\n\t\t\ttypeOf: function( obj ) {\n\t\t\t\tvar type;\n\t\t\t\tif ( obj === null ) {\n\t\t\t\t\ttype = "null";\n\t\t\t\t} else if ( typeof obj === "undefined" ) {\n\t\t\t\t\ttype = "undefined";\n\t\t\t\t} else if ( QUnit.is( "regexp", obj ) ) {\n\t\t\t\t\ttype = "regexp";\n\t\t\t\t} else if ( QUnit.is( "date", obj ) ) {\n\t\t\t\t\ttype = "date";\n\t\t\t\t} else if ( QUnit.is( "function", obj ) ) {\n\t\t\t\t\ttype = "function";\n\t\t\t\t} else if ( obj.setInterval !== undefined &&\n\t\t\t\t\t\tobj.document !== undefined &&\n\t\t\t\t\t\tobj.nodeType === undefined ) {\n\t\t\t\t\ttype = "window";\n\t\t\t\t} else if ( obj.nodeType === 9 ) {\n\t\t\t\t\ttype = "document";\n\t\t\t\t} else if ( obj.nodeType ) {\n\t\t\t\t\ttype = "node";\n\t\t\t\t} else if (\n\n\t\t\t\t\t// Native arrays\n\t\t\t\t\ttoString.call( obj ) === "[object Array]" ||\n\n\t\t\t\t\t// NodeList objects\n\t\t\t\t\t( typeof obj.length === "number" && obj.item !== undefined &&\n\t\t\t\t\t( obj.length ? obj.item( 0 ) === obj[ 0 ] : ( obj.item( 0 ) === null &&\n\t\t\t\t\tobj[ 0 ] === undefined ) ) )\n\t\t\t\t) {\n\t\t\t\t\ttype = "array";\n\t\t\t\t} else if ( obj.constructor === Error.prototype.constructor ) {\n\t\t\t\t\ttype = "error";\n\t\t\t\t} else {\n\t\t\t\t\ttype = typeof obj;\n\t\t\t\t}\n\t\t\t\treturn type;\n\t\t\t},\n\n\t\t\tseparator: function() {\n\t\t\t\treturn this.multiline ? this.HTML ? "
" : "\\n" : this.HTML ? " " : " ";\n\t\t\t},\n\n\t\t\t// Extra can be a number, shortcut for increasing-calling-decreasing\n\t\t\tindent: function( extra ) {\n\t\t\t\tif ( !this.multiline ) {\n\t\t\t\t\treturn "";\n\t\t\t\t}\n\t\t\t\tvar chr = this.indentChar;\n\t\t\t\tif ( this.HTML ) {\n\t\t\t\t\tchr = chr.replace( /\\t/g, " " ).replace( / /g, " " );\n\t\t\t\t}\n\t\t\t\treturn new Array( this.depth + ( extra || 0 ) ).join( chr );\n\t\t\t},\n\t\t\tup: function( a ) {\n\t\t\t\tthis.depth += a || 1;\n\t\t\t},\n\t\t\tdown: function( a ) {\n\t\t\t\tthis.depth -= a || 1;\n\t\t\t},\n\t\t\tsetParser: function( name, parser ) {\n\t\t\t\tthis.parsers[ name ] = parser;\n\t\t\t},\n\n\t\t\t// The next 3 are exposed so you can use them\n\t\t\tquote: quote,\n\t\t\tliteral: literal,\n\t\t\tjoin: join,\n\t\t\tdepth: 1,\n\t\t\tmaxDepth: QUnit.config.maxDepth,\n\n\t\t\t// This is the list of parsers, to modify them, use dump.setParser\n\t\t\tparsers: {\n\t\t\t\twindow: "[Window]",\n\t\t\t\tdocument: "[Document]",\n\t\t\t\terror: function( error ) {\n\t\t\t\t\treturn "Error(\\"" + error.message + "\\")";\n\t\t\t\t},\n\t\t\t\tunknown: "[Unknown]",\n\t\t\t\t"null": "null",\n\t\t\t\t"undefined": "undefined",\n\t\t\t\t"function": function( fn ) {\n\t\t\t\t\tvar ret = "function",\n\n\t\t\t\t\t\t// Functions never have name in IE\n\t\t\t\t\t\tname = "name" in fn ? fn.name : ( reName.exec( fn ) || [] )[ 1 ];\n\n\t\t\t\t\tif ( name ) {\n\t\t\t\t\t\tret += " " + name;\n\t\t\t\t\t}\n\t\t\t\t\tret += "(";\n\n\t\t\t\t\tret = [ ret, dump.parse( fn, "functionArgs" ), "){" ].join( "" );\n\t\t\t\t\treturn join( ret, dump.parse( fn, "functionCode" ), "}" );\n\t\t\t\t},\n\t\t\t\tarray: array,\n\t\t\t\tnodelist: array,\n\t\t\t\t"arguments": array,\n\t\t\t\tobject: function( map, stack ) {\n\t\t\t\t\tvar keys, key, val, i, nonEnumerableProperties,\n\t\t\t\t\t\tret = [];\n\n\t\t\t\t\tif ( dump.maxDepth && dump.depth > dump.maxDepth ) {\n\t\t\t\t\t\treturn "[object Object]";\n\t\t\t\t\t}\n\n\t\t\t\t\tdump.up();\n\t\t\t\t\tkeys = [];\n\t\t\t\t\tfor ( key in map ) {\n\t\t\t\t\t\tkeys.push( key );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Some properties are not always enumerable on Error objects.\n\t\t\t\t\tnonEnumerableProperties = [ "message", "name" ];\n\t\t\t\t\tfor ( i in nonEnumerableProperties ) {\n\t\t\t\t\t\tkey = nonEnumerableProperties[ i ];\n\t\t\t\t\t\tif ( key in map && inArray( key, keys ) < 0 ) {\n\t\t\t\t\t\t\tkeys.push( key );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tkeys.sort();\n\t\t\t\t\tfor ( i = 0; i < keys.length; i++ ) {\n\t\t\t\t\t\tkey = keys[ i ];\n\t\t\t\t\t\tval = map[ key ];\n\t\t\t\t\t\tret.push( dump.parse( key, "key" ) + ": " +\n\t\t\t\t\t\t\tdump.parse( val, undefined, stack ) );\n\t\t\t\t\t}\n\t\t\t\t\tdump.down();\n\t\t\t\t\treturn join( "{", ret, "}" );\n\t\t\t\t},\n\t\t\t\tnode: function( node ) {\n\t\t\t\t\tvar len, i, val,\n\t\t\t\t\t\topen = dump.HTML ? "<" : "<",\n\t\t\t\t\t\tclose = dump.HTML ? ">" : ">",\n\t\t\t\t\t\ttag = node.nodeName.toLowerCase(),\n\t\t\t\t\t\tret = open + tag,\n\t\t\t\t\t\tattrs = node.attributes;\n\n\t\t\t\t\tif ( attrs ) {\n\t\t\t\t\t\tfor ( i = 0, len = attrs.length; i < len; i++ ) {\n\t\t\t\t\t\t\tval = attrs[ i ].nodeValue;\n\n\t\t\t\t\t\t\t// IE6 includes all attributes in .attributes, even ones not explicitly\n\t\t\t\t\t\t\t// set. Those have values like undefined, null, 0, false, "" or\n\t\t\t\t\t\t\t// "inherit".\n\t\t\t\t\t\t\tif ( val && val !== "inherit" ) {\n\t\t\t\t\t\t\t\tret += " " + attrs[ i ].nodeName + "=" +\n\t\t\t\t\t\t\t\t\tdump.parse( val, "attribute" );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tret += close;\n\n\t\t\t\t\t// Show content of TextNode or CDATASection\n\t\t\t\t\tif ( node.nodeType === 3 || node.nodeType === 4 ) {\n\t\t\t\t\t\tret += node.nodeValue;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn ret + open + "/" + tag + close;\n\t\t\t\t},\n\n\t\t\t\t// Function calls it internally, it\'s the arguments part of the function\n\t\t\t\tfunctionArgs: function( fn ) {\n\t\t\t\t\tvar args,\n\t\t\t\t\t\tl = fn.length;\n\n\t\t\t\t\tif ( !l ) {\n\t\t\t\t\t\treturn "";\n\t\t\t\t\t}\n\n\t\t\t\t\targs = new Array( l );\n\t\t\t\t\twhile ( l-- ) {\n\n\t\t\t\t\t\t// 97 is \'a\'\n\t\t\t\t\t\targs[ l ] = String.fromCharCode( 97 + l );\n\t\t\t\t\t}\n\t\t\t\t\treturn " " + args.join( ", " ) + " ";\n\t\t\t\t},\n\n\t\t\t\t// Object calls it internally, the key part of an item in a map\n\t\t\t\tkey: quote,\n\n\t\t\t\t// Function calls it internally, it\'s the content of the function\n\t\t\t\tfunctionCode: "[code]",\n\n\t\t\t\t// Node calls it internally, it\'s a html attribute value\n\t\t\t\tattribute: quote,\n\t\t\t\tstring: quote,\n\t\t\t\tdate: quote,\n\t\t\t\tregexp: literal,\n\t\t\t\tnumber: literal,\n\t\t\t\t"boolean": literal\n\t\t\t},\n\n\t\t\t// If true, entities are escaped ( <, >, \\t, space and \\n )\n\t\t\tHTML: false,\n\n\t\t\t// Indentation unit\n\t\t\tindentChar: " ",\n\n\t\t\t// If true, items in a collection, are separated by a \\n, else just a space.\n\t\t\tmultiline: true\n\t\t};\n\n\treturn dump;\n}() );\n\n// Back compat\nQUnit.jsDump = QUnit.dump;\n\n// Deprecated\n// Extend assert methods to QUnit for Backwards compatibility\n( function() {\n\tvar i,\n\t\tassertions = Assert.prototype;\n\n\tfunction applyCurrent( current ) {\n\t\treturn function() {\n\t\t\tvar assert = new Assert( QUnit.config.current );\n\t\t\tcurrent.apply( assert, arguments );\n\t\t};\n\t}\n\n\tfor ( i in assertions ) {\n\t\tQUnit[ i ] = applyCurrent( assertions[ i ] );\n\t}\n}() );\n\n// For browser, export only select globals\nif ( defined.document ) {\n\n\t( function() {\n\t\tvar i, l,\n\t\t\tkeys = [\n\t\t\t\t"test",\n\t\t\t\t"module",\n\t\t\t\t"expect",\n\t\t\t\t"asyncTest",\n\t\t\t\t"start",\n\t\t\t\t"stop",\n\t\t\t\t"ok",\n\t\t\t\t"notOk",\n\t\t\t\t"equal",\n\t\t\t\t"notEqual",\n\t\t\t\t"propEqual",\n\t\t\t\t"notPropEqual",\n\t\t\t\t"deepEqual",\n\t\t\t\t"notDeepEqual",\n\t\t\t\t"strictEqual",\n\t\t\t\t"notStrictEqual",\n\t\t\t\t"throws",\n\t\t\t\t"raises"\n\t\t\t];\n\n\t\tfor ( i = 0, l = keys.length; i < l; i++ ) {\n\t\t\twindow[ keys[ i ] ] = QUnit[ keys[ i ] ];\n\t\t}\n\t}() );\n\n\twindow.QUnit = QUnit;\n}\n\n// For nodejs\nif ( typeof module !== "undefined" && module && module.exports ) {\n\tmodule.exports = QUnit;\n\n\t// For consistency with CommonJS environments\' exports\n\tmodule.exports.QUnit = QUnit;\n}\n\n// For CommonJS with exports, but without module.exports, like Rhino\nif ( typeof exports !== "undefined" && exports ) {\n\texports.QUnit = QUnit;\n}\n\nif ( typeof define === "function" && define.amd ) {\n\tdefine( function() {\n\t\treturn QUnit;\n\t} );\n\tQUnit.config.autostart = false;\n}\n\n// Get a reference to the global object, like window in browsers\n}( ( function() {\n\treturn this;\n}() ) ) );\n\n( function() {\n\n// Only interact with URLs via window.location\nvar location = typeof window !== "undefined" && window.location;\nif ( !location ) {\n\treturn;\n}\n\nvar urlParams = getUrlParams();\n\nQUnit.urlParams = urlParams;\n\n// Match module/test by inclusion in an array\nQUnit.config.moduleId = [].concat( urlParams.moduleId || [] );\nQUnit.config.testId = [].concat( urlParams.testId || [] );\n\n// Exact case-insensitive match of the module name\nQUnit.config.module = urlParams.module;\n\n// Regular expression or case-insenstive substring match against "moduleName: testName"\nQUnit.config.filter = urlParams.filter;\n\n// Test order randomization\nif ( urlParams.seed === true ) {\n\n\t// Generate a random seed if the option is specified without a value\n\tQUnit.config.seed = Math.random().toString( 36 ).slice( 2 );\n} else if ( urlParams.seed ) {\n\tQUnit.config.seed = urlParams.seed;\n}\n\n// Add URL-parameter-mapped config values with UI form rendering data\nQUnit.config.urlConfig.push(\n\t{\n\t\tid: "hidepassed",\n\t\tlabel: "Hide passed tests",\n\t\ttooltip: "Only show tests and assertions that fail. Stored as query-strings."\n\t},\n\t{\n\t\tid: "noglobals",\n\t\tlabel: "Check for Globals",\n\t\ttooltip: "Enabling this will test if any test introduces new properties on the " +\n\t\t\t"global object (`window` in Browsers). Stored as query-strings."\n\t},\n\t{\n\t\tid: "notrycatch",\n\t\tlabel: "No try-catch",\n\t\ttooltip: "Enabling this will run tests outside of a try-catch block. Makes debugging " +\n\t\t\t"exceptions in IE reasonable. Stored as query-strings."\n\t}\n);\n\nQUnit.begin( function() {\n\tvar i, option,\n\t\turlConfig = QUnit.config.urlConfig;\n\n\tfor ( i = 0; i < urlConfig.length; i++ ) {\n\n\t\t// Options can be either strings or objects with nonempty "id" properties\n\t\toption = QUnit.config.urlConfig[ i ];\n\t\tif ( typeof option !== "string" ) {\n\t\t\toption = option.id;\n\t\t}\n\n\t\tif ( QUnit.config[ option ] === undefined ) {\n\t\t\tQUnit.config[ option ] = urlParams[ option ];\n\t\t}\n\t}\n} );\n\nfunction getUrlParams() {\n\tvar i, param, name, value;\n\tvar urlParams = {};\n\tvar params = location.search.slice( 1 ).split( "&" );\n\tvar length = params.length;\n\n\tfor ( i = 0; i < length; i++ ) {\n\t\tif ( params[ i ] ) {\n\t\t\tparam = params[ i ].split( "=" );\n\t\t\tname = decodeURIComponent( param[ 0 ] );\n\n\t\t\t// Allow just a key to turn on a flag, e.g., test.html?noglobals\n\t\t\tvalue = param.length === 1 ||\n\t\t\t\tdecodeURIComponent( param.slice( 1 ).join( "=" ) ) ;\n\t\t\tif ( urlParams[ name ] ) {\n\t\t\t\turlParams[ name ] = [].concat( urlParams[ name ], value );\n\t\t\t} else {\n\t\t\t\turlParams[ name ] = value;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn urlParams;\n}\n\n// Don\'t load the HTML Reporter on non-browser environments\nif ( typeof window === "undefined" || !window.document ) {\n\treturn;\n}\n\n// Deprecated QUnit.init - Ref #530\n// Re-initialize the configuration options\nQUnit.init = function() {\n\tvar config = QUnit.config;\n\n\tconfig.stats = { all: 0, bad: 0 };\n\tconfig.moduleStats = { all: 0, bad: 0 };\n\tconfig.started = 0;\n\tconfig.updateRate = 1000;\n\tconfig.blocking = false;\n\tconfig.autostart = true;\n\tconfig.autorun = false;\n\tconfig.filter = "";\n\tconfig.queue = [];\n\n\tappendInterface();\n};\n\nvar config = QUnit.config,\n\tdocument = window.document,\n\tcollapseNext = false,\n\thasOwn = Object.prototype.hasOwnProperty,\n\tunfilteredUrl = setUrl( { filter: undefined, module: undefined,\n\t\tmoduleId: undefined, testId: undefined } ),\n\tdefined = {\n\t\tsessionStorage: ( function() {\n\t\t\tvar x = "qunit-test-string";\n\t\t\ttry {\n\t\t\t\tsessionStorage.setItem( x, x );\n\t\t\t\tsessionStorage.removeItem( x );\n\t\t\t\treturn true;\n\t\t\t} catch ( e ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}() )\n\t},\n\tmodulesList = [];\n\n/**\n* Escape text for attribute or text content.\n*/\nfunction escapeText( s ) {\n\tif ( !s ) {\n\t\treturn "";\n\t}\n\ts = s + "";\n\n\t// Both single quotes and double quotes (for attributes)\n\treturn s.replace( /[\'"<>&]/g, function( s ) {\n\t\tswitch ( s ) {\n\t\tcase "\'":\n\t\t\treturn "'";\n\t\tcase "\\"":\n\t\t\treturn """;\n\t\tcase "<":\n\t\t\treturn "<";\n\t\tcase ">":\n\t\t\treturn ">";\n\t\tcase "&":\n\t\t\treturn "&";\n\t\t}\n\t} );\n}\n\n/**\n * @param {HTMLElement} elem\n * @param {string} type\n * @param {Function} fn\n */\nfunction addEvent( elem, type, fn ) {\n\tif ( elem.addEventListener ) {\n\n\t\t// Standards-based browsers\n\t\telem.addEventListener( type, fn, false );\n\t} else if ( elem.attachEvent ) {\n\n\t\t// Support: IE <9\n\t\telem.attachEvent( "on" + type, function() {\n\t\t\tvar event = window.event;\n\t\t\tif ( !event.target ) {\n\t\t\t\tevent.target = event.srcElement || document;\n\t\t\t}\n\n\t\t\tfn.call( elem, event );\n\t\t} );\n\t}\n}\n\n/**\n * @param {Array|NodeList} elems\n * @param {string} type\n * @param {Function} fn\n */\nfunction addEvents( elems, type, fn ) {\n\tvar i = elems.length;\n\twhile ( i-- ) {\n\t\taddEvent( elems[ i ], type, fn );\n\t}\n}\n\nfunction hasClass( elem, name ) {\n\treturn ( " " + elem.className + " " ).indexOf( " " + name + " " ) >= 0;\n}\n\nfunction addClass( elem, name ) {\n\tif ( !hasClass( elem, name ) ) {\n\t\telem.className += ( elem.className ? " " : "" ) + name;\n\t}\n}\n\nfunction toggleClass( elem, name, force ) {\n\tif ( force || typeof force === "undefined" && !hasClass( elem, name ) ) {\n\t\taddClass( elem, name );\n\t} else {\n\t\tremoveClass( elem, name );\n\t}\n}\n\nfunction removeClass( elem, name ) {\n\tvar set = " " + elem.className + " ";\n\n\t// Class name may appear multiple times\n\twhile ( set.indexOf( " " + name + " " ) >= 0 ) {\n\t\tset = set.replace( " " + name + " ", " " );\n\t}\n\n\t// Trim for prettiness\n\telem.className = typeof set.trim === "function" ? set.trim() : set.replace( /^\\s+|\\s+$/g, "" );\n}\n\nfunction id( name ) {\n\treturn document.getElementById && document.getElementById( name );\n}\n\nfunction getUrlConfigHtml() {\n\tvar i, j, val,\n\t\tescaped, escapedTooltip,\n\t\tselection = false,\n\t\turlConfig = config.urlConfig,\n\t\turlConfigHtml = "";\n\n\tfor ( i = 0; i < urlConfig.length; i++ ) {\n\n\t\t// Options can be either strings or objects with nonempty "id" properties\n\t\tval = config.urlConfig[ i ];\n\t\tif ( typeof val === "string" ) {\n\t\t\tval = {\n\t\t\t\tid: val,\n\t\t\t\tlabel: val\n\t\t\t};\n\t\t}\n\n\t\tescaped = escapeText( val.id );\n\t\tescapedTooltip = escapeText( val.tooltip );\n\n\t\tif ( !val.value || typeof val.value === "string" ) {\n\t\t\turlConfigHtml += "";\n\t\t} else {\n\t\t\turlConfigHtml += "";\n\t\t}\n\t}\n\n\treturn urlConfigHtml;\n}\n\n// Handle "click" events on toolbar checkboxes and "change" for select menus.\n// Updates the URL with the new state of `config.urlConfig` values.\nfunction toolbarChanged() {\n\tvar updatedUrl, value, tests,\n\t\tfield = this,\n\t\tparams = {};\n\n\t// Detect if field is a select menu or a checkbox\n\tif ( "selectedIndex" in field ) {\n\t\tvalue = field.options[ field.selectedIndex ].value || undefined;\n\t} else {\n\t\tvalue = field.checked ? ( field.defaultValue || true ) : undefined;\n\t}\n\n\tparams[ field.name ] = value;\n\tupdatedUrl = setUrl( params );\n\n\t// Check if we can apply the change without a page refresh\n\tif ( "hidepassed" === field.name && "replaceState" in window.history ) {\n\t\tQUnit.urlParams[ field.name ] = value;\n\t\tconfig[ field.name ] = value || false;\n\t\ttests = id( "qunit-tests" );\n\t\tif ( tests ) {\n\t\t\ttoggleClass( tests, "hidepass", value || false );\n\t\t}\n\t\twindow.history.replaceState( null, "", updatedUrl );\n\t} else {\n\t\twindow.location = updatedUrl;\n\t}\n}\n\nfunction setUrl( params ) {\n\tvar key, arrValue, i,\n\t\tquerystring = "?",\n\t\tlocation = window.location;\n\n\tparams = QUnit.extend( QUnit.extend( {}, QUnit.urlParams ), params );\n\n\tfor ( key in params ) {\n\n\t\t// Skip inherited or undefined properties\n\t\tif ( hasOwn.call( params, key ) && params[ key ] !== undefined ) {\n\n\t\t\t// Output a parameter for each value of this key (but usually just one)\n\t\t\tarrValue = [].concat( params[ key ] );\n\t\t\tfor ( i = 0; i < arrValue.length; i++ ) {\n\t\t\t\tquerystring += encodeURIComponent( key );\n\t\t\t\tif ( arrValue[ i ] !== true ) {\n\t\t\t\t\tquerystring += "=" + encodeURIComponent( arrValue[ i ] );\n\t\t\t\t}\n\t\t\t\tquerystring += "&";\n\t\t\t}\n\t\t}\n\t}\n\treturn location.protocol + "//" + location.host +\n\t\tlocation.pathname + querystring.slice( 0, -1 );\n}\n\nfunction applyUrlParams() {\n\tvar selectedModule,\n\t\tmodulesList = id( "qunit-modulefilter" ),\n\t\tfilter = id( "qunit-filter-input" ).value;\n\n\tselectedModule = modulesList ?\n\t\tdecodeURIComponent( modulesList.options[ modulesList.selectedIndex ].value ) :\n\t\tundefined;\n\n\twindow.location = setUrl( {\n\t\tmodule: ( selectedModule === "" ) ? undefined : selectedModule,\n\t\tfilter: ( filter === "" ) ? undefined : filter,\n\n\t\t// Remove moduleId and testId filters\n\t\tmoduleId: undefined,\n\t\ttestId: undefined\n\t} );\n}\n\nfunction toolbarUrlConfigContainer() {\n\tvar urlConfigContainer = document.createElement( "span" );\n\n\turlConfigContainer.innerHTML = getUrlConfigHtml();\n\taddClass( urlConfigContainer, "qunit-url-config" );\n\n\t// For oldIE support:\n\t// * Add handlers to the individual elements instead of the container\n\t// * Use "click" instead of "change" for checkboxes\n\taddEvents( urlConfigContainer.getElementsByTagName( "input" ), "click", toolbarChanged );\n\taddEvents( urlConfigContainer.getElementsByTagName( "select" ), "change", toolbarChanged );\n\n\treturn urlConfigContainer;\n}\n\nfunction toolbarLooseFilter() {\n\tvar filter = document.createElement( "form" ),\n\t\tlabel = document.createElement( "label" ),\n\t\tinput = document.createElement( "input" ),\n\t\tbutton = document.createElement( "button" );\n\n\taddClass( filter, "qunit-filter" );\n\n\tlabel.innerHTML = "Filter: ";\n\n\tinput.type = "text";\n\tinput.value = config.filter || "";\n\tinput.name = "filter";\n\tinput.id = "qunit-filter-input";\n\n\tbutton.innerHTML = "Go";\n\n\tlabel.appendChild( input );\n\n\tfilter.appendChild( label );\n\tfilter.appendChild( button );\n\taddEvent( filter, "submit", function( ev ) {\n\t\tapplyUrlParams();\n\n\t\tif ( ev && ev.preventDefault ) {\n\t\t\tev.preventDefault();\n\t\t}\n\n\t\treturn false;\n\t} );\n\n\treturn filter;\n}\n\nfunction toolbarModuleFilterHtml() {\n\tvar i,\n\t\tmoduleFilterHtml = "";\n\n\tif ( !modulesList.length ) {\n\t\treturn false;\n\t}\n\n\tmoduleFilterHtml += "" +\n\t\t"";\n\n\treturn moduleFilterHtml;\n}\n\nfunction toolbarModuleFilter() {\n\tvar toolbar = id( "qunit-testrunner-toolbar" ),\n\t\tmoduleFilter = document.createElement( "span" ),\n\t\tmoduleFilterHtml = toolbarModuleFilterHtml();\n\n\tif ( !toolbar || !moduleFilterHtml ) {\n\t\treturn false;\n\t}\n\n\tmoduleFilter.setAttribute( "id", "qunit-modulefilter-container" );\n\tmoduleFilter.innerHTML = moduleFilterHtml;\n\n\taddEvent( moduleFilter.lastChild, "change", applyUrlParams );\n\n\ttoolbar.appendChild( moduleFilter );\n}\n\nfunction appendToolbar() {\n\tvar toolbar = id( "qunit-testrunner-toolbar" );\n\n\tif ( toolbar ) {\n\t\ttoolbar.appendChild( toolbarUrlConfigContainer() );\n\t\ttoolbar.appendChild( toolbarLooseFilter() );\n\t\ttoolbarModuleFilter();\n\t}\n}\n\nfunction appendHeader() {\n\tvar header = id( "qunit-header" );\n\n\tif ( header ) {\n\t\theader.innerHTML = "" + header.innerHTML +\n\t\t\t" ";\n\t}\n}\n\nfunction appendBanner() {\n\tvar banner = id( "qunit-banner" );\n\n\tif ( banner ) {\n\t\tbanner.className = "";\n\t}\n}\n\nfunction appendTestResults() {\n\tvar tests = id( "qunit-tests" ),\n\t\tresult = id( "qunit-testresult" );\n\n\tif ( result ) {\n\t\tresult.parentNode.removeChild( result );\n\t}\n\n\tif ( tests ) {\n\t\ttests.innerHTML = "";\n\t\tresult = document.createElement( "p" );\n\t\tresult.id = "qunit-testresult";\n\t\tresult.className = "result";\n\t\ttests.parentNode.insertBefore( result, tests );\n\t\tresult.innerHTML = "Running...
 ";\n\t}\n}\n\nfunction storeFixture() {\n\tvar fixture = id( "qunit-fixture" );\n\tif ( fixture ) {\n\t\tconfig.fixture = fixture.innerHTML;\n\t}\n}\n\nfunction appendFilteredTest() {\n\tvar testId = QUnit.config.testId;\n\tif ( !testId || testId.length <= 0 ) {\n\t\treturn "";\n\t}\n\treturn "
Rerunning selected tests: " +\n\t\tescapeText( testId.join( ", " ) ) +\n\t\t" Run all tests
";\n}\n\nfunction appendUserAgent() {\n\tvar userAgent = id( "qunit-userAgent" );\n\n\tif ( userAgent ) {\n\t\tuserAgent.innerHTML = "";\n\t\tuserAgent.appendChild(\n\t\t\tdocument.createTextNode(\n\t\t\t\t"QUnit " + QUnit.version + "; " + navigator.userAgent\n\t\t\t)\n\t\t);\n\t}\n}\n\nfunction appendInterface() {\n\tvar qunit = id( "qunit" );\n\n\tif ( qunit ) {\n\t\tqunit.innerHTML =\n\t\t\t"

" + escapeText( document.title ) + "

" +\n\t\t\t"

" +\n\t\t\t"
" +\n\t\t\tappendFilteredTest() +\n\t\t\t"

" +\n\t\t\t"
    ";\n\t}\n\n\tappendHeader();\n\tappendBanner();\n\tappendTestResults();\n\tappendUserAgent();\n\tappendToolbar();\n}\n\nfunction appendTestsList( modules ) {\n\tvar i, l, x, z, test, moduleObj;\n\n\tfor ( i = 0, l = modules.length; i < l; i++ ) {\n\t\tmoduleObj = modules[ i ];\n\n\t\tfor ( x = 0, z = moduleObj.tests.length; x < z; x++ ) {\n\t\t\ttest = moduleObj.tests[ x ];\n\n\t\t\tappendTest( test.name, test.testId, moduleObj.name );\n\t\t}\n\t}\n}\n\nfunction appendTest( name, testId, moduleName ) {\n\tvar title, rerunTrigger, testBlock, assertList,\n\t\ttests = id( "qunit-tests" );\n\n\tif ( !tests ) {\n\t\treturn;\n\t}\n\n\ttitle = document.createElement( "strong" );\n\ttitle.innerHTML = getNameHtml( name, moduleName );\n\n\trerunTrigger = document.createElement( "a" );\n\trerunTrigger.innerHTML = "Rerun";\n\trerunTrigger.href = setUrl( { testId: testId } );\n\n\ttestBlock = document.createElement( "li" );\n\ttestBlock.appendChild( title );\n\ttestBlock.appendChild( rerunTrigger );\n\ttestBlock.id = "qunit-test-output-" + testId;\n\n\tassertList = document.createElement( "ol" );\n\tassertList.className = "qunit-assert-list";\n\n\ttestBlock.appendChild( assertList );\n\n\ttests.appendChild( testBlock );\n}\n\n// HTML Reporter initialization and load\nQUnit.begin( function( details ) {\n\tvar i, moduleObj, tests;\n\n\t// Sort modules by name for the picker\n\tfor ( i = 0; i < details.modules.length; i++ ) {\n\t\tmoduleObj = details.modules[ i ];\n\t\tif ( moduleObj.name ) {\n\t\t\tmodulesList.push( moduleObj.name );\n\t\t}\n\t}\n\tmodulesList.sort( function( a, b ) {\n\t\treturn a.localeCompare( b );\n\t} );\n\n\t// Capture fixture HTML from the page\n\tstoreFixture();\n\n\t// Initialize QUnit elements\n\tappendInterface();\n\tappendTestsList( details.modules );\n\ttests = id( "qunit-tests" );\n\tif ( tests && config.hidepassed ) {\n\t\taddClass( tests, "hidepass" );\n\t}\n} );\n\nQUnit.done( function( details ) {\n\tvar i, key,\n\t\tbanner = id( "qunit-banner" ),\n\t\ttests = id( "qunit-tests" ),\n\t\thtml = [\n\t\t\t"Tests completed in ",\n\t\t\tdetails.runtime,\n\t\t\t" milliseconds.
    ",\n\t\t\t"",\n\t\t\tdetails.passed,\n\t\t\t" assertions of ",\n\t\t\tdetails.total,\n\t\t\t" passed, ",\n\t\t\tdetails.failed,\n\t\t\t" failed."\n\t\t].join( "" );\n\n\tif ( banner ) {\n\t\tbanner.className = details.failed ? "qunit-fail" : "qunit-pass";\n\t}\n\n\tif ( tests ) {\n\t\tid( "qunit-testresult" ).innerHTML = html;\n\t}\n\n\tif ( config.altertitle && document.title ) {\n\n\t\t// Show \u2716 for good, \u2714 for bad suite result in title\n\t\t// use escape sequences in case file gets loaded with non-utf-8-charset\n\t\tdocument.title = [\n\t\t\t( details.failed ? "\\u2716" : "\\u2714" ),\n\t\t\tdocument.title.replace( /^[\\u2714\\u2716] /i, "" )\n\t\t].join( " " );\n\t}\n\n\t// Clear own sessionStorage items if all tests passed\n\tif ( config.reorder && defined.sessionStorage && details.failed === 0 ) {\n\t\tfor ( i = 0; i < sessionStorage.length; i++ ) {\n\t\t\tkey = sessionStorage.key( i++ );\n\t\t\tif ( key.indexOf( "qunit-test-" ) === 0 ) {\n\t\t\t\tsessionStorage.removeItem( key );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Scroll back to top to show results\n\tif ( config.scrolltop && window.scrollTo ) {\n\t\twindow.scrollTo( 0, 0 );\n\t}\n} );\n\nfunction getNameHtml( name, module ) {\n\tvar nameHtml = "";\n\n\tif ( module ) {\n\t\tnameHtml = "" + escapeText( module ) + ": ";\n\t}\n\n\tnameHtml += "" + escapeText( name ) + "";\n\n\treturn nameHtml;\n}\n\nQUnit.testStart( function( details ) {\n\tvar running, testBlock, bad;\n\n\ttestBlock = id( "qunit-test-output-" + details.testId );\n\tif ( testBlock ) {\n\t\ttestBlock.className = "running";\n\t} else {\n\n\t\t// Report later registered tests\n\t\tappendTest( details.name, details.testId, details.module );\n\t}\n\n\trunning = id( "qunit-testresult" );\n\tif ( running ) {\n\t\tbad = QUnit.config.reorder && defined.sessionStorage &&\n\t\t\t+sessionStorage.getItem( "qunit-test-" + details.module + "-" + details.name );\n\n\t\trunning.innerHTML = ( bad ?\n\t\t\t"Rerunning previously failed test:
    " :\n\t\t\t"Running:
    " ) +\n\t\t\tgetNameHtml( details.name, details.module );\n\t}\n\n} );\n\nfunction stripHtml( string ) {\n\n\t// Strip tags, html entity and whitespaces\n\treturn string.replace( /<\\/?[^>]+(>|$)/g, "" ).replace( /\\"/g, "" ).replace( /\\s+/g, "" );\n}\n\nQUnit.log( function( details ) {\n\tvar assertList, assertLi,\n\t\tmessage, expected, actual, diff,\n\t\tshowDiff = false,\n\t\ttestItem = id( "qunit-test-output-" + details.testId );\n\n\tif ( !testItem ) {\n\t\treturn;\n\t}\n\n\tmessage = escapeText( details.message ) || ( details.result ? "okay" : "failed" );\n\tmessage = "" + message + "";\n\tmessage += "@ " + details.runtime + " ms";\n\n\t// The pushFailure doesn\'t provide details.expected\n\t// when it calls, it\'s implicit to also not show expected and diff stuff\n\t// Also, we need to check details.expected existence, as it can exist and be undefined\n\tif ( !details.result && hasOwn.call( details, "expected" ) ) {\n\t\tif ( details.negative ) {\n\t\t\texpected = "NOT " + QUnit.dump.parse( details.expected );\n\t\t} else {\n\t\t\texpected = QUnit.dump.parse( details.expected );\n\t\t}\n\n\t\tactual = QUnit.dump.parse( details.actual );\n\t\tmessage += "";\n\n\t\tif ( actual !== expected ) {\n\n\t\t\tmessage += "";\n\n\t\t\t// Don\'t show diff if actual or expected are booleans\n\t\t\tif ( !( /^(true|false)$/.test( actual ) ) &&\n\t\t\t\t\t!( /^(true|false)$/.test( expected ) ) ) {\n\t\t\t\tdiff = QUnit.diff( expected, actual );\n\t\t\t\tshowDiff = stripHtml( diff ).length !==\n\t\t\t\t\tstripHtml( expected ).length +\n\t\t\t\t\tstripHtml( actual ).length;\n\t\t\t}\n\n\t\t\t// Don\'t show diff if expected and actual are totally different\n\t\t\tif ( showDiff ) {\n\t\t\t\tmessage += "";\n\t\t\t}\n\t\t} else if ( expected.indexOf( "[object Array]" ) !== -1 ||\n\t\t\t\texpected.indexOf( "[object Object]" ) !== -1 ) {\n\t\t\tmessage += "";\n\t\t} else {\n\t\t\tmessage += "";\n\t\t}\n\n\t\tif ( details.source ) {\n\t\t\tmessage += "";\n\t\t}\n\n\t\tmessage += "
    Expected:
    " +\n\t\t\tescapeText( expected ) +\n\t\t\t"
    Result:
    " +\n\t\t\t\tescapeText( actual ) + "
    Diff:
    " +\n\t\t\t\t\tdiff + "
    Message: " +\n\t\t\t\t"Diff suppressed as the depth of object is more than current max depth (" +\n\t\t\t\tQUnit.config.maxDepth + ").

    Hint: Use QUnit.dump.maxDepth to " +\n\t\t\t\t" run with a higher max depth or " +\n\t\t\t\t"Rerun without max depth.

    Message: " +\n\t\t\t\t"Diff suppressed as the expected and actual results have an equivalent" +\n\t\t\t\t" serialization
    Source:
    " +\n\t\t\t\tescapeText( details.source ) + "
    ";\n\n\t// This occurs when pushFailure is set and we have an extracted stack trace\n\t} else if ( !details.result && details.source ) {\n\t\tmessage += "" +\n\t\t\t"" +\n\t\t\t"
    Source:
    " +\n\t\t\tescapeText( details.source ) + "
    ";\n\t}\n\n\tassertList = testItem.getElementsByTagName( "ol" )[ 0 ];\n\n\tassertLi = document.createElement( "li" );\n\tassertLi.className = details.result ? "pass" : "fail";\n\tassertLi.innerHTML = message;\n\tassertList.appendChild( assertLi );\n} );\n\nQUnit.testDone( function( details ) {\n\tvar testTitle, time, testItem, assertList,\n\t\tgood, bad, testCounts, skipped, sourceName,\n\t\ttests = id( "qunit-tests" );\n\n\tif ( !tests ) {\n\t\treturn;\n\t}\n\n\ttestItem = id( "qunit-test-output-" + details.testId );\n\n\tassertList = testItem.getElementsByTagName( "ol" )[ 0 ];\n\n\tgood = details.passed;\n\tbad = details.failed;\n\n\t// Store result when possible\n\tif ( config.reorder && defined.sessionStorage ) {\n\t\tif ( bad ) {\n\t\t\tsessionStorage.setItem( "qunit-test-" + details.module + "-" + details.name, bad );\n\t\t} else {\n\t\t\tsessionStorage.removeItem( "qunit-test-" + details.module + "-" + details.name );\n\t\t}\n\t}\n\n\tif ( bad === 0 ) {\n\n\t\t// Collapse the passing tests\n\t\taddClass( assertList, "qunit-collapsed" );\n\t} else if ( bad && config.collapse && !collapseNext ) {\n\n\t\t// Skip collapsing the first failing test\n\t\tcollapseNext = true;\n\t} else {\n\n\t\t// Collapse remaining tests\n\t\taddClass( assertList, "qunit-collapsed" );\n\t}\n\n\t// The testItem.firstChild is the test name\n\ttestTitle = testItem.firstChild;\n\n\ttestCounts = bad ?\n\t\t"" + bad + ", " + "" + good + ", " :\n\t\t"";\n\n\ttestTitle.innerHTML += " (" + testCounts +\n\t\tdetails.assertions.length + ")";\n\n\tif ( details.skipped ) {\n\t\ttestItem.className = "skipped";\n\t\tskipped = document.createElement( "em" );\n\t\tskipped.className = "qunit-skipped-label";\n\t\tskipped.innerHTML = "skipped";\n\t\ttestItem.insertBefore( skipped, testTitle );\n\t} else {\n\t\taddEvent( testTitle, "click", function() {\n\t\t\ttoggleClass( assertList, "qunit-collapsed" );\n\t\t} );\n\n\t\ttestItem.className = bad ? "fail" : "pass";\n\n\t\ttime = document.createElement( "span" );\n\t\ttime.className = "runtime";\n\t\ttime.innerHTML = details.runtime + " ms";\n\t\ttestItem.insertBefore( time, assertList );\n\t}\n\n\t// Show the source of the test when showing assertions\n\tif ( details.source ) {\n\t\tsourceName = document.createElement( "p" );\n\t\tsourceName.innerHTML = "Source: " + details.source;\n\t\taddClass( sourceName, "qunit-source" );\n\t\tif ( bad === 0 ) {\n\t\t\taddClass( sourceName, "qunit-collapsed" );\n\t\t}\n\t\taddEvent( testTitle, "click", function() {\n\t\t\ttoggleClass( sourceName, "qunit-collapsed" );\n\t\t} );\n\t\ttestItem.appendChild( sourceName );\n\t}\n} );\n\n// Avoid readyState issue with phantomjs\n// Ref: #818\nvar notPhantom = ( function( p ) {\n\treturn !( p && p.version && p.version.major > 0 );\n} )( window.phantom );\n\nif ( notPhantom && document.readyState === "complete" ) {\n\tQUnit.load();\n} else {\n\taddEvent( window, "load", QUnit.load );\n}\n\n/*\n * This file is a modified version of google-diff-match-patch\'s JavaScript implementation\n * (https://code.google.com/p/google-diff-match-patch/source/browse/trunk/javascript/diff_match_patch_uncompressed.js),\n * modifications are licensed as more fully set forth in LICENSE.txt.\n *\n * The original source of google-diff-match-patch is attributable and licensed as follows:\n *\n * Copyright 2006 Google Inc.\n * https://code.google.com/p/google-diff-match-patch/\n *\n * Licensed under the Apache License, Version 2.0 (the "License");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an "AS IS" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * More Info:\n * https://code.google.com/p/google-diff-match-patch/\n *\n * Usage: QUnit.diff(expected, actual)\n *\n */\nQUnit.diff = ( function() {\n\tfunction DiffMatchPatch() {\n\t}\n\n\t// DIFF FUNCTIONS\n\n\t/**\n\t * The data structure representing a diff is an array of tuples:\n\t * [[DIFF_DELETE, \'Hello\'], [DIFF_INSERT, \'Goodbye\'], [DIFF_EQUAL, \' world.\']]\n\t * which means: delete \'Hello\', add \'Goodbye\' and keep \' world.\'\n\t */\n\tvar DIFF_DELETE = -1,\n\t\tDIFF_INSERT = 1,\n\t\tDIFF_EQUAL = 0;\n\n\t/**\n\t * Find the differences between two texts. Simplifies the problem by stripping\n\t * any common prefix or suffix off the texts before diffing.\n\t * @param {string} text1 Old string to be diffed.\n\t * @param {string} text2 New string to be diffed.\n\t * @param {boolean=} optChecklines Optional speedup flag. If present and false,\n\t * then don\'t run a line-level diff first to identify the changed areas.\n\t * Defaults to true, which does a faster, slightly less optimal diff.\n\t * @return {!Array.} Array of diff tuples.\n\t */\n\tDiffMatchPatch.prototype.DiffMain = function( text1, text2, optChecklines ) {\n\t\tvar deadline, checklines, commonlength,\n\t\t\tcommonprefix, commonsuffix, diffs;\n\n\t\t// The diff must be complete in up to 1 second.\n\t\tdeadline = ( new Date() ).getTime() + 1000;\n\n\t\t// Check for null inputs.\n\t\tif ( text1 === null || text2 === null ) {\n\t\t\tthrow new Error( "Null input. (DiffMain)" );\n\t\t}\n\n\t\t// Check for equality (speedup).\n\t\tif ( text1 === text2 ) {\n\t\t\tif ( text1 ) {\n\t\t\t\treturn [\n\t\t\t\t\t[ DIFF_EQUAL, text1 ]\n\t\t\t\t];\n\t\t\t}\n\t\t\treturn [];\n\t\t}\n\n\t\tif ( typeof optChecklines === "undefined" ) {\n\t\t\toptChecklines = true;\n\t\t}\n\n\t\tchecklines = optChecklines;\n\n\t\t// Trim off common prefix (speedup).\n\t\tcommonlength = this.diffCommonPrefix( text1, text2 );\n\t\tcommonprefix = text1.substring( 0, commonlength );\n\t\ttext1 = text1.substring( commonlength );\n\t\ttext2 = text2.substring( commonlength );\n\n\t\t// Trim off common suffix (speedup).\n\t\tcommonlength = this.diffCommonSuffix( text1, text2 );\n\t\tcommonsuffix = text1.substring( text1.length - commonlength );\n\t\ttext1 = text1.substring( 0, text1.length - commonlength );\n\t\ttext2 = text2.substring( 0, text2.length - commonlength );\n\n\t\t// Compute the diff on the middle block.\n\t\tdiffs = this.diffCompute( text1, text2, checklines, deadline );\n\n\t\t// Restore the prefix and suffix.\n\t\tif ( commonprefix ) {\n\t\t\tdiffs.unshift( [ DIFF_EQUAL, commonprefix ] );\n\t\t}\n\t\tif ( commonsuffix ) {\n\t\t\tdiffs.push( [ DIFF_EQUAL, commonsuffix ] );\n\t\t}\n\t\tthis.diffCleanupMerge( diffs );\n\t\treturn diffs;\n\t};\n\n\t/**\n\t * Reduce the number of edits by eliminating operationally trivial equalities.\n\t * @param {!Array.} diffs Array of diff tuples.\n\t */\n\tDiffMatchPatch.prototype.diffCleanupEfficiency = function( diffs ) {\n\t\tvar changes, equalities, equalitiesLength, lastequality,\n\t\t\tpointer, preIns, preDel, postIns, postDel;\n\t\tchanges = false;\n\t\tequalities = []; // Stack of indices where equalities are found.\n\t\tequalitiesLength = 0; // Keeping our own length var is faster in JS.\n\t\t/** @type {?string} */\n\t\tlastequality = null;\n\n\t\t// Always equal to diffs[equalities[equalitiesLength - 1]][1]\n\t\tpointer = 0; // Index of current position.\n\n\t\t// Is there an insertion operation before the last equality.\n\t\tpreIns = false;\n\n\t\t// Is there a deletion operation before the last equality.\n\t\tpreDel = false;\n\n\t\t// Is there an insertion operation after the last equality.\n\t\tpostIns = false;\n\n\t\t// Is there a deletion operation after the last equality.\n\t\tpostDel = false;\n\t\twhile ( pointer < diffs.length ) {\n\n\t\t\t// Equality found.\n\t\t\tif ( diffs[ pointer ][ 0 ] === DIFF_EQUAL ) {\n\t\t\t\tif ( diffs[ pointer ][ 1 ].length < 4 && ( postIns || postDel ) ) {\n\n\t\t\t\t\t// Candidate found.\n\t\t\t\t\tequalities[ equalitiesLength++ ] = pointer;\n\t\t\t\t\tpreIns = postIns;\n\t\t\t\t\tpreDel = postDel;\n\t\t\t\t\tlastequality = diffs[ pointer ][ 1 ];\n\t\t\t\t} else {\n\n\t\t\t\t\t// Not a candidate, and can never become one.\n\t\t\t\t\tequalitiesLength = 0;\n\t\t\t\t\tlastequality = null;\n\t\t\t\t}\n\t\t\t\tpostIns = postDel = false;\n\n\t\t\t// An insertion or deletion.\n\t\t\t} else {\n\n\t\t\t\tif ( diffs[ pointer ][ 0 ] === DIFF_DELETE ) {\n\t\t\t\t\tpostDel = true;\n\t\t\t\t} else {\n\t\t\t\t\tpostIns = true;\n\t\t\t\t}\n\n\t\t\t\t/*\n\t\t\t\t * Five types to be split:\n\t\t\t\t * ABXYCD\n\t\t\t\t * AXCD\n\t\t\t\t * ABXC\n\t\t\t\t * AXCD\n\t\t\t\t * ABXC\n\t\t\t\t */\n\t\t\t\tif ( lastequality && ( ( preIns && preDel && postIns && postDel ) ||\n\t\t\t\t\t\t( ( lastequality.length < 2 ) &&\n\t\t\t\t\t\t( preIns + preDel + postIns + postDel ) === 3 ) ) ) {\n\n\t\t\t\t\t// Duplicate record.\n\t\t\t\t\tdiffs.splice(\n\t\t\t\t\t\tequalities[ equalitiesLength - 1 ],\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t[ DIFF_DELETE, lastequality ]\n\t\t\t\t\t);\n\n\t\t\t\t\t// Change second copy to insert.\n\t\t\t\t\tdiffs[ equalities[ equalitiesLength - 1 ] + 1 ][ 0 ] = DIFF_INSERT;\n\t\t\t\t\tequalitiesLength--; // Throw away the equality we just deleted;\n\t\t\t\t\tlastequality = null;\n\t\t\t\t\tif ( preIns && preDel ) {\n\n\t\t\t\t\t\t// No changes made which could affect previous entry, keep going.\n\t\t\t\t\t\tpostIns = postDel = true;\n\t\t\t\t\t\tequalitiesLength = 0;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tequalitiesLength--; // Throw away the previous equality.\n\t\t\t\t\t\tpointer = equalitiesLength > 0 ? equalities[ equalitiesLength - 1 ] : -1;\n\t\t\t\t\t\tpostIns = postDel = false;\n\t\t\t\t\t}\n\t\t\t\t\tchanges = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tpointer++;\n\t\t}\n\n\t\tif ( changes ) {\n\t\t\tthis.diffCleanupMerge( diffs );\n\t\t}\n\t};\n\n\t/**\n\t * Convert a diff array into a pretty HTML report.\n\t * @param {!Array.} diffs Array of diff tuples.\n\t * @param {integer} string to be beautified.\n\t * @return {string} HTML representation.\n\t */\n\tDiffMatchPatch.prototype.diffPrettyHtml = function( diffs ) {\n\t\tvar op, data, x,\n\t\t\thtml = [];\n\t\tfor ( x = 0; x < diffs.length; x++ ) {\n\t\t\top = diffs[ x ][ 0 ]; // Operation (insert, delete, equal)\n\t\t\tdata = diffs[ x ][ 1 ]; // Text of change.\n\t\t\tswitch ( op ) {\n\t\t\tcase DIFF_INSERT:\n\t\t\t\thtml[ x ] = "" + escapeText( data ) + "";\n\t\t\t\tbreak;\n\t\t\tcase DIFF_DELETE:\n\t\t\t\thtml[ x ] = "" + escapeText( data ) + "";\n\t\t\t\tbreak;\n\t\t\tcase DIFF_EQUAL:\n\t\t\t\thtml[ x ] = "" + escapeText( data ) + "";\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\treturn html.join( "" );\n\t};\n\n\t/**\n\t * Determine the common prefix of two strings.\n\t * @param {string} text1 First string.\n\t * @param {string} text2 Second string.\n\t * @return {number} The number of characters common to the start of each\n\t * string.\n\t */\n\tDiffMatchPatch.prototype.diffCommonPrefix = function( text1, text2 ) {\n\t\tvar pointermid, pointermax, pointermin, pointerstart;\n\n\t\t// Quick check for common null cases.\n\t\tif ( !text1 || !text2 || text1.charAt( 0 ) !== text2.charAt( 0 ) ) {\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Binary search.\n\t\t// Performance analysis: https://neil.fraser.name/news/2007/10/09/\n\t\tpointermin = 0;\n\t\tpointermax = Math.min( text1.length, text2.length );\n\t\tpointermid = pointermax;\n\t\tpointerstart = 0;\n\t\twhile ( pointermin < pointermid ) {\n\t\t\tif ( text1.substring( pointerstart, pointermid ) ===\n\t\t\t\t\ttext2.substring( pointerstart, pointermid ) ) {\n\t\t\t\tpointermin = pointermid;\n\t\t\t\tpointerstart = pointermin;\n\t\t\t} else {\n\t\t\t\tpointermax = pointermid;\n\t\t\t}\n\t\t\tpointermid = Math.floor( ( pointermax - pointermin ) / 2 + pointermin );\n\t\t}\n\t\treturn pointermid;\n\t};\n\n\t/**\n\t * Determine the common suffix of two strings.\n\t * @param {string} text1 First string.\n\t * @param {string} text2 Second string.\n\t * @return {number} The number of characters common to the end of each string.\n\t */\n\tDiffMatchPatch.prototype.diffCommonSuffix = function( text1, text2 ) {\n\t\tvar pointermid, pointermax, pointermin, pointerend;\n\n\t\t// Quick check for common null cases.\n\t\tif ( !text1 ||\n\t\t\t\t!text2 ||\n\t\t\t\ttext1.charAt( text1.length - 1 ) !== text2.charAt( text2.length - 1 ) ) {\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Binary search.\n\t\t// Performance analysis: https://neil.fraser.name/news/2007/10/09/\n\t\tpointermin = 0;\n\t\tpointermax = Math.min( text1.length, text2.length );\n\t\tpointermid = pointermax;\n\t\tpointerend = 0;\n\t\twhile ( pointermin < pointermid ) {\n\t\t\tif ( text1.substring( text1.length - pointermid, text1.length - pointerend ) ===\n\t\t\t\t\ttext2.substring( text2.length - pointermid, text2.length - pointerend ) ) {\n\t\t\t\tpointermin = pointermid;\n\t\t\t\tpointerend = pointermin;\n\t\t\t} else {\n\t\t\t\tpointermax = pointermid;\n\t\t\t}\n\t\t\tpointermid = Math.floor( ( pointermax - pointermin ) / 2 + pointermin );\n\t\t}\n\t\treturn pointermid;\n\t};\n\n\t/**\n\t * Find the differences between two texts. Assumes that the texts do not\n\t * have any common prefix or suffix.\n\t * @param {string} text1 Old string to be diffed.\n\t * @param {string} text2 New string to be diffed.\n\t * @param {boolean} checklines Speedup flag. If false, then don\'t run a\n\t * line-level diff first to identify the changed areas.\n\t * If true, then run a faster, slightly less optimal diff.\n\t * @param {number} deadline Time when the diff should be complete by.\n\t * @return {!Array.} Array of diff tuples.\n\t * @private\n\t */\n\tDiffMatchPatch.prototype.diffCompute = function( text1, text2, checklines, deadline ) {\n\t\tvar diffs, longtext, shorttext, i, hm,\n\t\t\ttext1A, text2A, text1B, text2B,\n\t\t\tmidCommon, diffsA, diffsB;\n\n\t\tif ( !text1 ) {\n\n\t\t\t// Just add some text (speedup).\n\t\t\treturn [\n\t\t\t\t[ DIFF_INSERT, text2 ]\n\t\t\t];\n\t\t}\n\n\t\tif ( !text2 ) {\n\n\t\t\t// Just delete some text (speedup).\n\t\t\treturn [\n\t\t\t\t[ DIFF_DELETE, text1 ]\n\t\t\t];\n\t\t}\n\n\t\tlongtext = text1.length > text2.length ? text1 : text2;\n\t\tshorttext = text1.length > text2.length ? text2 : text1;\n\t\ti = longtext.indexOf( shorttext );\n\t\tif ( i !== -1 ) {\n\n\t\t\t// Shorter text is inside the longer text (speedup).\n\t\t\tdiffs = [\n\t\t\t\t[ DIFF_INSERT, longtext.substring( 0, i ) ],\n\t\t\t\t[ DIFF_EQUAL, shorttext ],\n\t\t\t\t[ DIFF_INSERT, longtext.substring( i + shorttext.length ) ]\n\t\t\t];\n\n\t\t\t// Swap insertions for deletions if diff is reversed.\n\t\t\tif ( text1.length > text2.length ) {\n\t\t\t\tdiffs[ 0 ][ 0 ] = diffs[ 2 ][ 0 ] = DIFF_DELETE;\n\t\t\t}\n\t\t\treturn diffs;\n\t\t}\n\n\t\tif ( shorttext.length === 1 ) {\n\n\t\t\t// Single character string.\n\t\t\t// After the previous speedup, the character can\'t be an equality.\n\t\t\treturn [\n\t\t\t\t[ DIFF_DELETE, text1 ],\n\t\t\t\t[ DIFF_INSERT, text2 ]\n\t\t\t];\n\t\t}\n\n\t\t// Check to see if the problem can be split in two.\n\t\thm = this.diffHalfMatch( text1, text2 );\n\t\tif ( hm ) {\n\n\t\t\t// A half-match was found, sort out the return data.\n\t\t\ttext1A = hm[ 0 ];\n\t\t\ttext1B = hm[ 1 ];\n\t\t\ttext2A = hm[ 2 ];\n\t\t\ttext2B = hm[ 3 ];\n\t\t\tmidCommon = hm[ 4 ];\n\n\t\t\t// Send both pairs off for separate processing.\n\t\t\tdiffsA = this.DiffMain( text1A, text2A, checklines, deadline );\n\t\t\tdiffsB = this.DiffMain( text1B, text2B, checklines, deadline );\n\n\t\t\t// Merge the results.\n\t\t\treturn diffsA.concat( [\n\t\t\t\t[ DIFF_EQUAL, midCommon ]\n\t\t\t], diffsB );\n\t\t}\n\n\t\tif ( checklines && text1.length > 100 && text2.length > 100 ) {\n\t\t\treturn this.diffLineMode( text1, text2, deadline );\n\t\t}\n\n\t\treturn this.diffBisect( text1, text2, deadline );\n\t};\n\n\t/**\n\t * Do the two texts share a substring which is at least half the length of the\n\t * longer text?\n\t * This speedup can produce non-minimal diffs.\n\t * @param {string} text1 First string.\n\t * @param {string} text2 Second string.\n\t * @return {Array.} Five element Array, containing the prefix of\n\t * text1, the suffix of text1, the prefix of text2, the suffix of\n\t * text2 and the common middle. Or null if there was no match.\n\t * @private\n\t */\n\tDiffMatchPatch.prototype.diffHalfMatch = function( text1, text2 ) {\n\t\tvar longtext, shorttext, dmp,\n\t\t\ttext1A, text2B, text2A, text1B, midCommon,\n\t\t\thm1, hm2, hm;\n\n\t\tlongtext = text1.length > text2.length ? text1 : text2;\n\t\tshorttext = text1.length > text2.length ? text2 : text1;\n\t\tif ( longtext.length < 4 || shorttext.length * 2 < longtext.length ) {\n\t\t\treturn null; // Pointless.\n\t\t}\n\t\tdmp = this; // \'this\' becomes \'window\' in a closure.\n\n\t\t/**\n\t\t * Does a substring of shorttext exist within longtext such that the substring\n\t\t * is at least half the length of longtext?\n\t\t * Closure, but does not reference any external variables.\n\t\t * @param {string} longtext Longer string.\n\t\t * @param {string} shorttext Shorter string.\n\t\t * @param {number} i Start index of quarter length substring within longtext.\n\t\t * @return {Array.} Five element Array, containing the prefix of\n\t\t * longtext, the suffix of longtext, the prefix of shorttext, the suffix\n\t\t * of shorttext and the common middle. Or null if there was no match.\n\t\t * @private\n\t\t */\n\t\tfunction diffHalfMatchI( longtext, shorttext, i ) {\n\t\t\tvar seed, j, bestCommon, prefixLength, suffixLength,\n\t\t\t\tbestLongtextA, bestLongtextB, bestShorttextA, bestShorttextB;\n\n\t\t\t// Start with a 1/4 length substring at position i as a seed.\n\t\t\tseed = longtext.substring( i, i + Math.floor( longtext.length / 4 ) );\n\t\t\tj = -1;\n\t\t\tbestCommon = "";\n\t\t\twhile ( ( j = shorttext.indexOf( seed, j + 1 ) ) !== -1 ) {\n\t\t\t\tprefixLength = dmp.diffCommonPrefix( longtext.substring( i ),\n\t\t\t\t\tshorttext.substring( j ) );\n\t\t\t\tsuffixLength = dmp.diffCommonSuffix( longtext.substring( 0, i ),\n\t\t\t\t\tshorttext.substring( 0, j ) );\n\t\t\t\tif ( bestCommon.length < suffixLength + prefixLength ) {\n\t\t\t\t\tbestCommon = shorttext.substring( j - suffixLength, j ) +\n\t\t\t\t\t\tshorttext.substring( j, j + prefixLength );\n\t\t\t\t\tbestLongtextA = longtext.substring( 0, i - suffixLength );\n\t\t\t\t\tbestLongtextB = longtext.substring( i + prefixLength );\n\t\t\t\t\tbestShorttextA = shorttext.substring( 0, j - suffixLength );\n\t\t\t\t\tbestShorttextB = shorttext.substring( j + prefixLength );\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( bestCommon.length * 2 >= longtext.length ) {\n\t\t\t\treturn [ bestLongtextA, bestLongtextB,\n\t\t\t\t\tbestShorttextA, bestShorttextB, bestCommon\n\t\t\t\t];\n\t\t\t} else {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\t// First check if the second quarter is the seed for a half-match.\n\t\thm1 = diffHalfMatchI( longtext, shorttext,\n\t\t\tMath.ceil( longtext.length / 4 ) );\n\n\t\t// Check again based on the third quarter.\n\t\thm2 = diffHalfMatchI( longtext, shorttext,\n\t\t\tMath.ceil( longtext.length / 2 ) );\n\t\tif ( !hm1 && !hm2 ) {\n\t\t\treturn null;\n\t\t} else if ( !hm2 ) {\n\t\t\thm = hm1;\n\t\t} else if ( !hm1 ) {\n\t\t\thm = hm2;\n\t\t} else {\n\n\t\t\t// Both matched. Select the longest.\n\t\t\thm = hm1[ 4 ].length > hm2[ 4 ].length ? hm1 : hm2;\n\t\t}\n\n\t\t// A half-match was found, sort out the return data.\n\t\ttext1A, text1B, text2A, text2B;\n\t\tif ( text1.length > text2.length ) {\n\t\t\ttext1A = hm[ 0 ];\n\t\t\ttext1B = hm[ 1 ];\n\t\t\ttext2A = hm[ 2 ];\n\t\t\ttext2B = hm[ 3 ];\n\t\t} else {\n\t\t\ttext2A = hm[ 0 ];\n\t\t\ttext2B = hm[ 1 ];\n\t\t\ttext1A = hm[ 2 ];\n\t\t\ttext1B = hm[ 3 ];\n\t\t}\n\t\tmidCommon = hm[ 4 ];\n\t\treturn [ text1A, text1B, text2A, text2B, midCommon ];\n\t};\n\n\t/**\n\t * Do a quick line-level diff on both strings, then rediff the parts for\n\t * greater accuracy.\n\t * This speedup can produce non-minimal diffs.\n\t * @param {string} text1 Old string to be diffed.\n\t * @param {string} text2 New string to be diffed.\n\t * @param {number} deadline Time when the diff should be complete by.\n\t * @return {!Array.} Array of diff tuples.\n\t * @private\n\t */\n\tDiffMatchPatch.prototype.diffLineMode = function( text1, text2, deadline ) {\n\t\tvar a, diffs, linearray, pointer, countInsert,\n\t\t\tcountDelete, textInsert, textDelete, j;\n\n\t\t// Scan the text on a line-by-line basis first.\n\t\ta = this.diffLinesToChars( text1, text2 );\n\t\ttext1 = a.chars1;\n\t\ttext2 = a.chars2;\n\t\tlinearray = a.lineArray;\n\n\t\tdiffs = this.DiffMain( text1, text2, false, deadline );\n\n\t\t// Convert the diff back to original text.\n\t\tthis.diffCharsToLines( diffs, linearray );\n\n\t\t// Eliminate freak matches (e.g. blank lines)\n\t\tthis.diffCleanupSemantic( diffs );\n\n\t\t// Rediff any replacement blocks, this time character-by-character.\n\t\t// Add a dummy entry at the end.\n\t\tdiffs.push( [ DIFF_EQUAL, "" ] );\n\t\tpointer = 0;\n\t\tcountDelete = 0;\n\t\tcountInsert = 0;\n\t\ttextDelete = "";\n\t\ttextInsert = "";\n\t\twhile ( pointer < diffs.length ) {\n\t\t\tswitch ( diffs[ pointer ][ 0 ] ) {\n\t\t\tcase DIFF_INSERT:\n\t\t\t\tcountInsert++;\n\t\t\t\ttextInsert += diffs[ pointer ][ 1 ];\n\t\t\t\tbreak;\n\t\t\tcase DIFF_DELETE:\n\t\t\t\tcountDelete++;\n\t\t\t\ttextDelete += diffs[ pointer ][ 1 ];\n\t\t\t\tbreak;\n\t\t\tcase DIFF_EQUAL:\n\n\t\t\t\t// Upon reaching an equality, check for prior redundancies.\n\t\t\t\tif ( countDelete >= 1 && countInsert >= 1 ) {\n\n\t\t\t\t\t// Delete the offending records and add the merged ones.\n\t\t\t\t\tdiffs.splice( pointer - countDelete - countInsert,\n\t\t\t\t\t\tcountDelete + countInsert );\n\t\t\t\t\tpointer = pointer - countDelete - countInsert;\n\t\t\t\t\ta = this.DiffMain( textDelete, textInsert, false, deadline );\n\t\t\t\t\tfor ( j = a.length - 1; j >= 0; j-- ) {\n\t\t\t\t\t\tdiffs.splice( pointer, 0, a[ j ] );\n\t\t\t\t\t}\n\t\t\t\t\tpointer = pointer + a.length;\n\t\t\t\t}\n\t\t\t\tcountInsert = 0;\n\t\t\t\tcountDelete = 0;\n\t\t\t\ttextDelete = "";\n\t\t\t\ttextInsert = "";\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tpointer++;\n\t\t}\n\t\tdiffs.pop(); // Remove the dummy entry at the end.\n\n\t\treturn diffs;\n\t};\n\n\t/**\n\t * Find the \'middle snake\' of a diff, split the problem in two\n\t * and return the recursively constructed diff.\n\t * See Myers 1986 paper: An O(ND) Difference Algorithm and Its Variations.\n\t * @param {string} text1 Old string to be diffed.\n\t * @param {string} text2 New string to be diffed.\n\t * @param {number} deadline Time at which to bail if not yet complete.\n\t * @return {!Array.} Array of diff tuples.\n\t * @private\n\t */\n\tDiffMatchPatch.prototype.diffBisect = function( text1, text2, deadline ) {\n\t\tvar text1Length, text2Length, maxD, vOffset, vLength,\n\t\t\tv1, v2, x, delta, front, k1start, k1end, k2start,\n\t\t\tk2end, k2Offset, k1Offset, x1, x2, y1, y2, d, k1, k2;\n\n\t\t// Cache the text lengths to prevent multiple calls.\n\t\ttext1Length = text1.length;\n\t\ttext2Length = text2.length;\n\t\tmaxD = Math.ceil( ( text1Length + text2Length ) / 2 );\n\t\tvOffset = maxD;\n\t\tvLength = 2 * maxD;\n\t\tv1 = new Array( vLength );\n\t\tv2 = new Array( vLength );\n\n\t\t// Setting all elements to -1 is faster in Chrome & Firefox than mixing\n\t\t// integers and undefined.\n\t\tfor ( x = 0; x < vLength; x++ ) {\n\t\t\tv1[ x ] = -1;\n\t\t\tv2[ x ] = -1;\n\t\t}\n\t\tv1[ vOffset + 1 ] = 0;\n\t\tv2[ vOffset + 1 ] = 0;\n\t\tdelta = text1Length - text2Length;\n\n\t\t// If the total number of characters is odd, then the front path will collide\n\t\t// with the reverse path.\n\t\tfront = ( delta % 2 !== 0 );\n\n\t\t// Offsets for start and end of k loop.\n\t\t// Prevents mapping of space beyond the grid.\n\t\tk1start = 0;\n\t\tk1end = 0;\n\t\tk2start = 0;\n\t\tk2end = 0;\n\t\tfor ( d = 0; d < maxD; d++ ) {\n\n\t\t\t// Bail out if deadline is reached.\n\t\t\tif ( ( new Date() ).getTime() > deadline ) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Walk the front path one step.\n\t\t\tfor ( k1 = -d + k1start; k1 <= d - k1end; k1 += 2 ) {\n\t\t\t\tk1Offset = vOffset + k1;\n\t\t\t\tif ( k1 === -d || ( k1 !== d && v1[ k1Offset - 1 ] < v1[ k1Offset + 1 ] ) ) {\n\t\t\t\t\tx1 = v1[ k1Offset + 1 ];\n\t\t\t\t} else {\n\t\t\t\t\tx1 = v1[ k1Offset - 1 ] + 1;\n\t\t\t\t}\n\t\t\t\ty1 = x1 - k1;\n\t\t\t\twhile ( x1 < text1Length && y1 < text2Length &&\n\t\t\t\t\ttext1.charAt( x1 ) === text2.charAt( y1 ) ) {\n\t\t\t\t\tx1++;\n\t\t\t\t\ty1++;\n\t\t\t\t}\n\t\t\t\tv1[ k1Offset ] = x1;\n\t\t\t\tif ( x1 > text1Length ) {\n\n\t\t\t\t\t// Ran off the right of the graph.\n\t\t\t\t\tk1end += 2;\n\t\t\t\t} else if ( y1 > text2Length ) {\n\n\t\t\t\t\t// Ran off the bottom of the graph.\n\t\t\t\t\tk1start += 2;\n\t\t\t\t} else if ( front ) {\n\t\t\t\t\tk2Offset = vOffset + delta - k1;\n\t\t\t\t\tif ( k2Offset >= 0 && k2Offset < vLength && v2[ k2Offset ] !== -1 ) {\n\n\t\t\t\t\t\t// Mirror x2 onto top-left coordinate system.\n\t\t\t\t\t\tx2 = text1Length - v2[ k2Offset ];\n\t\t\t\t\t\tif ( x1 >= x2 ) {\n\n\t\t\t\t\t\t\t// Overlap detected.\n\t\t\t\t\t\t\treturn this.diffBisectSplit( text1, text2, x1, y1, deadline );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Walk the reverse path one step.\n\t\t\tfor ( k2 = -d + k2start; k2 <= d - k2end; k2 += 2 ) {\n\t\t\t\tk2Offset = vOffset + k2;\n\t\t\t\tif ( k2 === -d || ( k2 !== d && v2[ k2Offset - 1 ] < v2[ k2Offset + 1 ] ) ) {\n\t\t\t\t\tx2 = v2[ k2Offset + 1 ];\n\t\t\t\t} else {\n\t\t\t\t\tx2 = v2[ k2Offset - 1 ] + 1;\n\t\t\t\t}\n\t\t\t\ty2 = x2 - k2;\n\t\t\t\twhile ( x2 < text1Length && y2 < text2Length &&\n\t\t\t\t\ttext1.charAt( text1Length - x2 - 1 ) ===\n\t\t\t\t\ttext2.charAt( text2Length - y2 - 1 ) ) {\n\t\t\t\t\tx2++;\n\t\t\t\t\ty2++;\n\t\t\t\t}\n\t\t\t\tv2[ k2Offset ] = x2;\n\t\t\t\tif ( x2 > text1Length ) {\n\n\t\t\t\t\t// Ran off the left of the graph.\n\t\t\t\t\tk2end += 2;\n\t\t\t\t} else if ( y2 > text2Length ) {\n\n\t\t\t\t\t// Ran off the top of the graph.\n\t\t\t\t\tk2start += 2;\n\t\t\t\t} else if ( !front ) {\n\t\t\t\t\tk1Offset = vOffset + delta - k2;\n\t\t\t\t\tif ( k1Offset >= 0 && k1Offset < vLength && v1[ k1Offset ] !== -1 ) {\n\t\t\t\t\t\tx1 = v1[ k1Offset ];\n\t\t\t\t\t\ty1 = vOffset + x1 - k1Offset;\n\n\t\t\t\t\t\t// Mirror x2 onto top-left coordinate system.\n\t\t\t\t\t\tx2 = text1Length - x2;\n\t\t\t\t\t\tif ( x1 >= x2 ) {\n\n\t\t\t\t\t\t\t// Overlap detected.\n\t\t\t\t\t\t\treturn this.diffBisectSplit( text1, text2, x1, y1, deadline );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Diff took too long and hit the deadline or\n\t\t// number of diffs equals number of characters, no commonality at all.\n\t\treturn [\n\t\t\t[ DIFF_DELETE, text1 ],\n\t\t\t[ DIFF_INSERT, text2 ]\n\t\t];\n\t};\n\n\t/**\n\t * Given the location of the \'middle snake\', split the diff in two parts\n\t * and recurse.\n\t * @param {string} text1 Old string to be diffed.\n\t * @param {string} text2 New string to be diffed.\n\t * @param {number} x Index of split point in text1.\n\t * @param {number} y Index of split point in text2.\n\t * @param {number} deadline Time at which to bail if not yet complete.\n\t * @return {!Array.} Array of diff tuples.\n\t * @private\n\t */\n\tDiffMatchPatch.prototype.diffBisectSplit = function( text1, text2, x, y, deadline ) {\n\t\tvar text1a, text1b, text2a, text2b, diffs, diffsb;\n\t\ttext1a = text1.substring( 0, x );\n\t\ttext2a = text2.substring( 0, y );\n\t\ttext1b = text1.substring( x );\n\t\ttext2b = text2.substring( y );\n\n\t\t// Compute both diffs serially.\n\t\tdiffs = this.DiffMain( text1a, text2a, false, deadline );\n\t\tdiffsb = this.DiffMain( text1b, text2b, false, deadline );\n\n\t\treturn diffs.concat( diffsb );\n\t};\n\n\t/**\n\t * Reduce the number of edits by eliminating semantically trivial equalities.\n\t * @param {!Array.} diffs Array of diff tuples.\n\t */\n\tDiffMatchPatch.prototype.diffCleanupSemantic = function( diffs ) {\n\t\tvar changes, equalities, equalitiesLength, lastequality,\n\t\t\tpointer, lengthInsertions2, lengthDeletions2, lengthInsertions1,\n\t\t\tlengthDeletions1, deletion, insertion, overlapLength1, overlapLength2;\n\t\tchanges = false;\n\t\tequalities = []; // Stack of indices where equalities are found.\n\t\tequalitiesLength = 0; // Keeping our own length var is faster in JS.\n\t\t/** @type {?string} */\n\t\tlastequality = null;\n\n\t\t// Always equal to diffs[equalities[equalitiesLength - 1]][1]\n\t\tpointer = 0; // Index of current position.\n\n\t\t// Number of characters that changed prior to the equality.\n\t\tlengthInsertions1 = 0;\n\t\tlengthDeletions1 = 0;\n\n\t\t// Number of characters that changed after the equality.\n\t\tlengthInsertions2 = 0;\n\t\tlengthDeletions2 = 0;\n\t\twhile ( pointer < diffs.length ) {\n\t\t\tif ( diffs[ pointer ][ 0 ] === DIFF_EQUAL ) { // Equality found.\n\t\t\t\tequalities[ equalitiesLength++ ] = pointer;\n\t\t\t\tlengthInsertions1 = lengthInsertions2;\n\t\t\t\tlengthDeletions1 = lengthDeletions2;\n\t\t\t\tlengthInsertions2 = 0;\n\t\t\t\tlengthDeletions2 = 0;\n\t\t\t\tlastequality = diffs[ pointer ][ 1 ];\n\t\t\t} else { // An insertion or deletion.\n\t\t\t\tif ( diffs[ pointer ][ 0 ] === DIFF_INSERT ) {\n\t\t\t\t\tlengthInsertions2 += diffs[ pointer ][ 1 ].length;\n\t\t\t\t} else {\n\t\t\t\t\tlengthDeletions2 += diffs[ pointer ][ 1 ].length;\n\t\t\t\t}\n\n\t\t\t\t// Eliminate an equality that is smaller or equal to the edits on both\n\t\t\t\t// sides of it.\n\t\t\t\tif ( lastequality && ( lastequality.length <=\n\t\t\t\t\t\tMath.max( lengthInsertions1, lengthDeletions1 ) ) &&\n\t\t\t\t\t\t( lastequality.length <= Math.max( lengthInsertions2,\n\t\t\t\t\t\t\tlengthDeletions2 ) ) ) {\n\n\t\t\t\t\t// Duplicate record.\n\t\t\t\t\tdiffs.splice(\n\t\t\t\t\t\tequalities[ equalitiesLength - 1 ],\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t[ DIFF_DELETE, lastequality ]\n\t\t\t\t\t);\n\n\t\t\t\t\t// Change second copy to insert.\n\t\t\t\t\tdiffs[ equalities[ equalitiesLength - 1 ] + 1 ][ 0 ] = DIFF_INSERT;\n\n\t\t\t\t\t// Throw away the equality we just deleted.\n\t\t\t\t\tequalitiesLength--;\n\n\t\t\t\t\t// Throw away the previous equality (it needs to be reevaluated).\n\t\t\t\t\tequalitiesLength--;\n\t\t\t\t\tpointer = equalitiesLength > 0 ? equalities[ equalitiesLength - 1 ] : -1;\n\n\t\t\t\t\t// Reset the counters.\n\t\t\t\t\tlengthInsertions1 = 0;\n\t\t\t\t\tlengthDeletions1 = 0;\n\t\t\t\t\tlengthInsertions2 = 0;\n\t\t\t\t\tlengthDeletions2 = 0;\n\t\t\t\t\tlastequality = null;\n\t\t\t\t\tchanges = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tpointer++;\n\t\t}\n\n\t\t// Normalize the diff.\n\t\tif ( changes ) {\n\t\t\tthis.diffCleanupMerge( diffs );\n\t\t}\n\n\t\t// Find any overlaps between deletions and insertions.\n\t\t// e.g: abcxxxxxxdef\n\t\t// -> abcxxxdef\n\t\t// e.g: xxxabcdefxxx\n\t\t// -> defxxxabc\n\t\t// Only extract an overlap if it is as big as the edit ahead or behind it.\n\t\tpointer = 1;\n\t\twhile ( pointer < diffs.length ) {\n\t\t\tif ( diffs[ pointer - 1 ][ 0 ] === DIFF_DELETE &&\n\t\t\t\t\tdiffs[ pointer ][ 0 ] === DIFF_INSERT ) {\n\t\t\t\tdeletion = diffs[ pointer - 1 ][ 1 ];\n\t\t\t\tinsertion = diffs[ pointer ][ 1 ];\n\t\t\t\toverlapLength1 = this.diffCommonOverlap( deletion, insertion );\n\t\t\t\toverlapLength2 = this.diffCommonOverlap( insertion, deletion );\n\t\t\t\tif ( overlapLength1 >= overlapLength2 ) {\n\t\t\t\t\tif ( overlapLength1 >= deletion.length / 2 ||\n\t\t\t\t\t\t\toverlapLength1 >= insertion.length / 2 ) {\n\n\t\t\t\t\t\t// Overlap found. Insert an equality and trim the surrounding edits.\n\t\t\t\t\t\tdiffs.splice(\n\t\t\t\t\t\t\tpointer,\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t[ DIFF_EQUAL, insertion.substring( 0, overlapLength1 ) ]\n\t\t\t\t\t\t);\n\t\t\t\t\t\tdiffs[ pointer - 1 ][ 1 ] =\n\t\t\t\t\t\t\tdeletion.substring( 0, deletion.length - overlapLength1 );\n\t\t\t\t\t\tdiffs[ pointer + 1 ][ 1 ] = insertion.substring( overlapLength1 );\n\t\t\t\t\t\tpointer++;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif ( overlapLength2 >= deletion.length / 2 ||\n\t\t\t\t\t\t\toverlapLength2 >= insertion.length / 2 ) {\n\n\t\t\t\t\t\t// Reverse overlap found.\n\t\t\t\t\t\t// Insert an equality and swap and trim the surrounding edits.\n\t\t\t\t\t\tdiffs.splice(\n\t\t\t\t\t\t\tpointer,\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t[ DIFF_EQUAL, deletion.substring( 0, overlapLength2 ) ]\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tdiffs[ pointer - 1 ][ 0 ] = DIFF_INSERT;\n\t\t\t\t\t\tdiffs[ pointer - 1 ][ 1 ] =\n\t\t\t\t\t\t\tinsertion.substring( 0, insertion.length - overlapLength2 );\n\t\t\t\t\t\tdiffs[ pointer + 1 ][ 0 ] = DIFF_DELETE;\n\t\t\t\t\t\tdiffs[ pointer + 1 ][ 1 ] =\n\t\t\t\t\t\t\tdeletion.substring( overlapLength2 );\n\t\t\t\t\t\tpointer++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tpointer++;\n\t\t\t}\n\t\t\tpointer++;\n\t\t}\n\t};\n\n\t/**\n\t * Determine if the suffix of one string is the prefix of another.\n\t * @param {string} text1 First string.\n\t * @param {string} text2 Second string.\n\t * @return {number} The number of characters common to the end of the first\n\t * string and the start of the second string.\n\t * @private\n\t */\n\tDiffMatchPatch.prototype.diffCommonOverlap = function( text1, text2 ) {\n\t\tvar text1Length, text2Length, textLength,\n\t\t\tbest, length, pattern, found;\n\n\t\t// Cache the text lengths to prevent multiple calls.\n\t\ttext1Length = text1.length;\n\t\ttext2Length = text2.length;\n\n\t\t// Eliminate the null case.\n\t\tif ( text1Length === 0 || text2Length === 0 ) {\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Truncate the longer string.\n\t\tif ( text1Length > text2Length ) {\n\t\t\ttext1 = text1.substring( text1Length - text2Length );\n\t\t} else if ( text1Length < text2Length ) {\n\t\t\ttext2 = text2.substring( 0, text1Length );\n\t\t}\n\t\ttextLength = Math.min( text1Length, text2Length );\n\n\t\t// Quick check for the worst case.\n\t\tif ( text1 === text2 ) {\n\t\t\treturn textLength;\n\t\t}\n\n\t\t// Start by looking for a single character match\n\t\t// and increase length until no match is found.\n\t\t// Performance analysis: https://neil.fraser.name/news/2010/11/04/\n\t\tbest = 0;\n\t\tlength = 1;\n\t\twhile ( true ) {\n\t\t\tpattern = text1.substring( textLength - length );\n\t\t\tfound = text2.indexOf( pattern );\n\t\t\tif ( found === -1 ) {\n\t\t\t\treturn best;\n\t\t\t}\n\t\t\tlength += found;\n\t\t\tif ( found === 0 || text1.substring( textLength - length ) ===\n\t\t\t\t\ttext2.substring( 0, length ) ) {\n\t\t\t\tbest = length;\n\t\t\t\tlength++;\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Split two texts into an array of strings. Reduce the texts to a string of\n\t * hashes where each Unicode character represents one line.\n\t * @param {string} text1 First string.\n\t * @param {string} text2 Second string.\n\t * @return {{chars1: string, chars2: string, lineArray: !Array.}}\n\t * An object containing the encoded text1, the encoded text2 and\n\t * the array of unique strings.\n\t * The zeroth element of the array of unique strings is intentionally blank.\n\t * @private\n\t */\n\tDiffMatchPatch.prototype.diffLinesToChars = function( text1, text2 ) {\n\t\tvar lineArray, lineHash, chars1, chars2;\n\t\tlineArray = []; // E.g. lineArray[4] === \'Hello\\n\'\n\t\tlineHash = {}; // E.g. lineHash[\'Hello\\n\'] === 4\n\n\t\t// \'\\x00\' is a valid character, but various debuggers don\'t like it.\n\t\t// So we\'ll insert a junk entry to avoid generating a null character.\n\t\tlineArray[ 0 ] = "";\n\n\t\t/**\n\t\t * Split a text into an array of strings. Reduce the texts to a string of\n\t\t * hashes where each Unicode character represents one line.\n\t\t * Modifies linearray and linehash through being a closure.\n\t\t * @param {string} text String to encode.\n\t\t * @return {string} Encoded string.\n\t\t * @private\n\t\t */\n\t\tfunction diffLinesToCharsMunge( text ) {\n\t\t\tvar chars, lineStart, lineEnd, lineArrayLength, line;\n\t\t\tchars = "";\n\n\t\t\t// Walk the text, pulling out a substring for each line.\n\t\t\t// text.split(\'\\n\') would would temporarily double our memory footprint.\n\t\t\t// Modifying text would create many large strings to garbage collect.\n\t\t\tlineStart = 0;\n\t\t\tlineEnd = -1;\n\n\t\t\t// Keeping our own length variable is faster than looking it up.\n\t\t\tlineArrayLength = lineArray.length;\n\t\t\twhile ( lineEnd < text.length - 1 ) {\n\t\t\t\tlineEnd = text.indexOf( "\\n", lineStart );\n\t\t\t\tif ( lineEnd === -1 ) {\n\t\t\t\t\tlineEnd = text.length - 1;\n\t\t\t\t}\n\t\t\t\tline = text.substring( lineStart, lineEnd + 1 );\n\t\t\t\tlineStart = lineEnd + 1;\n\n\t\t\t\tif ( lineHash.hasOwnProperty ? lineHash.hasOwnProperty( line ) :\n\t\t\t\t\t\t\t( lineHash[ line ] !== undefined ) ) {\n\t\t\t\t\tchars += String.fromCharCode( lineHash[ line ] );\n\t\t\t\t} else {\n\t\t\t\t\tchars += String.fromCharCode( lineArrayLength );\n\t\t\t\t\tlineHash[ line ] = lineArrayLength;\n\t\t\t\t\tlineArray[ lineArrayLength++ ] = line;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn chars;\n\t\t}\n\n\t\tchars1 = diffLinesToCharsMunge( text1 );\n\t\tchars2 = diffLinesToCharsMunge( text2 );\n\t\treturn {\n\t\t\tchars1: chars1,\n\t\t\tchars2: chars2,\n\t\t\tlineArray: lineArray\n\t\t};\n\t};\n\n\t/**\n\t * Rehydrate the text in a diff from a string of line hashes to real lines of\n\t * text.\n\t * @param {!Array.} diffs Array of diff tuples.\n\t * @param {!Array.} lineArray Array of unique strings.\n\t * @private\n\t */\n\tDiffMatchPatch.prototype.diffCharsToLines = function( diffs, lineArray ) {\n\t\tvar x, chars, text, y;\n\t\tfor ( x = 0; x < diffs.length; x++ ) {\n\t\t\tchars = diffs[ x ][ 1 ];\n\t\t\ttext = [];\n\t\t\tfor ( y = 0; y < chars.length; y++ ) {\n\t\t\t\ttext[ y ] = lineArray[ chars.charCodeAt( y ) ];\n\t\t\t}\n\t\t\tdiffs[ x ][ 1 ] = text.join( "" );\n\t\t}\n\t};\n\n\t/**\n\t * Reorder and merge like edit sections. Merge equalities.\n\t * Any edit section can move as long as it doesn\'t cross an equality.\n\t * @param {!Array.} diffs Array of diff tuples.\n\t */\n\tDiffMatchPatch.prototype.diffCleanupMerge = function( diffs ) {\n\t\tvar pointer, countDelete, countInsert, textInsert, textDelete,\n\t\t\tcommonlength, changes, diffPointer, position;\n\t\tdiffs.push( [ DIFF_EQUAL, "" ] ); // Add a dummy entry at the end.\n\t\tpointer = 0;\n\t\tcountDelete = 0;\n\t\tcountInsert = 0;\n\t\ttextDelete = "";\n\t\ttextInsert = "";\n\t\tcommonlength;\n\t\twhile ( pointer < diffs.length ) {\n\t\t\tswitch ( diffs[ pointer ][ 0 ] ) {\n\t\t\tcase DIFF_INSERT:\n\t\t\t\tcountInsert++;\n\t\t\t\ttextInsert += diffs[ pointer ][ 1 ];\n\t\t\t\tpointer++;\n\t\t\t\tbreak;\n\t\t\tcase DIFF_DELETE:\n\t\t\t\tcountDelete++;\n\t\t\t\ttextDelete += diffs[ pointer ][ 1 ];\n\t\t\t\tpointer++;\n\t\t\t\tbreak;\n\t\t\tcase DIFF_EQUAL:\n\n\t\t\t\t// Upon reaching an equality, check for prior redundancies.\n\t\t\t\tif ( countDelete + countInsert > 1 ) {\n\t\t\t\t\tif ( countDelete !== 0 && countInsert !== 0 ) {\n\n\t\t\t\t\t\t// Factor out any common prefixes.\n\t\t\t\t\t\tcommonlength = this.diffCommonPrefix( textInsert, textDelete );\n\t\t\t\t\t\tif ( commonlength !== 0 ) {\n\t\t\t\t\t\t\tif ( ( pointer - countDelete - countInsert ) > 0 &&\n\t\t\t\t\t\t\t\t\tdiffs[ pointer - countDelete - countInsert - 1 ][ 0 ] ===\n\t\t\t\t\t\t\t\t\tDIFF_EQUAL ) {\n\t\t\t\t\t\t\t\tdiffs[ pointer - countDelete - countInsert - 1 ][ 1 ] +=\n\t\t\t\t\t\t\t\t\ttextInsert.substring( 0, commonlength );\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tdiffs.splice( 0, 0, [ DIFF_EQUAL,\n\t\t\t\t\t\t\t\t\ttextInsert.substring( 0, commonlength )\n\t\t\t\t\t\t\t\t] );\n\t\t\t\t\t\t\t\tpointer++;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\ttextInsert = textInsert.substring( commonlength );\n\t\t\t\t\t\t\ttextDelete = textDelete.substring( commonlength );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Factor out any common suffixies.\n\t\t\t\t\t\tcommonlength = this.diffCommonSuffix( textInsert, textDelete );\n\t\t\t\t\t\tif ( commonlength !== 0 ) {\n\t\t\t\t\t\t\tdiffs[ pointer ][ 1 ] = textInsert.substring( textInsert.length -\n\t\t\t\t\t\t\t\t\tcommonlength ) + diffs[ pointer ][ 1 ];\n\t\t\t\t\t\t\ttextInsert = textInsert.substring( 0, textInsert.length -\n\t\t\t\t\t\t\t\tcommonlength );\n\t\t\t\t\t\t\ttextDelete = textDelete.substring( 0, textDelete.length -\n\t\t\t\t\t\t\t\tcommonlength );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Delete the offending records and add the merged ones.\n\t\t\t\t\tif ( countDelete === 0 ) {\n\t\t\t\t\t\tdiffs.splice( pointer - countInsert,\n\t\t\t\t\t\t\tcountDelete + countInsert, [ DIFF_INSERT, textInsert ] );\n\t\t\t\t\t} else if ( countInsert === 0 ) {\n\t\t\t\t\t\tdiffs.splice( pointer - countDelete,\n\t\t\t\t\t\t\tcountDelete + countInsert, [ DIFF_DELETE, textDelete ] );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdiffs.splice(\n\t\t\t\t\t\t\tpointer - countDelete - countInsert,\n\t\t\t\t\t\t\tcountDelete + countInsert,\n\t\t\t\t\t\t\t[ DIFF_DELETE, textDelete ], [ DIFF_INSERT, textInsert ]\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tpointer = pointer - countDelete - countInsert +\n\t\t\t\t\t\t( countDelete ? 1 : 0 ) + ( countInsert ? 1 : 0 ) + 1;\n\t\t\t\t} else if ( pointer !== 0 && diffs[ pointer - 1 ][ 0 ] === DIFF_EQUAL ) {\n\n\t\t\t\t\t// Merge this equality with the previous one.\n\t\t\t\t\tdiffs[ pointer - 1 ][ 1 ] += diffs[ pointer ][ 1 ];\n\t\t\t\t\tdiffs.splice( pointer, 1 );\n\t\t\t\t} else {\n\t\t\t\t\tpointer++;\n\t\t\t\t}\n\t\t\t\tcountInsert = 0;\n\t\t\t\tcountDelete = 0;\n\t\t\t\ttextDelete = "";\n\t\t\t\ttextInsert = "";\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif ( diffs[ diffs.length - 1 ][ 1 ] === "" ) {\n\t\t\tdiffs.pop(); // Remove the dummy entry at the end.\n\t\t}\n\n\t\t// Second pass: look for single edits surrounded on both sides by equalities\n\t\t// which can be shifted sideways to eliminate an equality.\n\t\t// e.g: ABAC -> ABAC\n\t\tchanges = false;\n\t\tpointer = 1;\n\n\t\t// Intentionally ignore the first and last element (don\'t need checking).\n\t\twhile ( pointer < diffs.length - 1 ) {\n\t\t\tif ( diffs[ pointer - 1 ][ 0 ] === DIFF_EQUAL &&\n\t\t\t\t\tdiffs[ pointer + 1 ][ 0 ] === DIFF_EQUAL ) {\n\n\t\t\t\tdiffPointer = diffs[ pointer ][ 1 ];\n\t\t\t\tposition = diffPointer.substring(\n\t\t\t\t\tdiffPointer.length - diffs[ pointer - 1 ][ 1 ].length\n\t\t\t\t);\n\n\t\t\t\t// This is a single edit surrounded by equalities.\n\t\t\t\tif ( position === diffs[ pointer - 1 ][ 1 ] ) {\n\n\t\t\t\t\t// Shift the edit over the previous equality.\n\t\t\t\t\tdiffs[ pointer ][ 1 ] = diffs[ pointer - 1 ][ 1 ] +\n\t\t\t\t\t\tdiffs[ pointer ][ 1 ].substring( 0, diffs[ pointer ][ 1 ].length -\n\t\t\t\t\t\t\tdiffs[ pointer - 1 ][ 1 ].length );\n\t\t\t\t\tdiffs[ pointer + 1 ][ 1 ] =\n\t\t\t\t\t\tdiffs[ pointer - 1 ][ 1 ] + diffs[ pointer + 1 ][ 1 ];\n\t\t\t\t\tdiffs.splice( pointer - 1, 1 );\n\t\t\t\t\tchanges = true;\n\t\t\t\t} else if ( diffPointer.substring( 0, diffs[ pointer + 1 ][ 1 ].length ) ===\n\t\t\t\t\t\tdiffs[ pointer + 1 ][ 1 ] ) {\n\n\t\t\t\t\t// Shift the edit over the next equality.\n\t\t\t\t\tdiffs[ pointer - 1 ][ 1 ] += diffs[ pointer + 1 ][ 1 ];\n\t\t\t\t\tdiffs[ pointer ][ 1 ] =\n\t\t\t\t\t\tdiffs[ pointer ][ 1 ].substring( diffs[ pointer + 1 ][ 1 ].length ) +\n\t\t\t\t\t\tdiffs[ pointer + 1 ][ 1 ];\n\t\t\t\t\tdiffs.splice( pointer + 1, 1 );\n\t\t\t\t\tchanges = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tpointer++;\n\t\t}\n\n\t\t// If shifts were made, the diff needs reordering and another shift sweep.\n\t\tif ( changes ) {\n\t\t\tthis.diffCleanupMerge( diffs );\n\t\t}\n\t};\n\n\treturn function( o, n ) {\n\t\tvar diff, output, text;\n\t\tdiff = new DiffMatchPatch();\n\t\toutput = diff.DiffMain( o, n );\n\t\tdiff.diffCleanupEfficiency( output );\n\t\ttext = diff.diffPrettyHtml( output );\n\n\t\treturn text;\n\t};\n}() );\n\n}() );\n'; + loader.global.define = undefined; + loader.global.module = undefined; + loader.global.exports = undefined; + loader.__exec({ + 'source': source, + 'address': module.uri + }); + loader.global.require = require; + loader.global.define = define; + return loader.get('@@global-helpers').retrieveGlobal(module.id, 'QUnit'); +}); +/*steal-css@1.3.2#css*/ +define('steal-css@1.3.2#css', [ + 'require', + 'exports', + 'module', + '@loader', + '@steal' +], function (require, exports, module) { + (function (global, require, exports, module) { + var loader = require('@loader'); + var steal = require('@steal'); + var isNode = typeof process === 'object' && {}.toString.call(process) === '[object process]'; + var importRegEx = /@import [^uU]['"]?([^'"\)]*)['"]?/g; + var resourceRegEx = /url\(['"]?([^'"\)]*)['"]?\)/g; + var waitSeconds = loader.cssOptions && loader.cssOptions.timeout ? parseInt(loader.cssOptions.timeout, 10) : 60; + var onloadCss = function (link, cb) { + var styleSheets = getDocument().styleSheets, i = styleSheets.length; + while (i--) { + if (styleSheets[i].href === link.href) { + return cb(); + } + } + setTimeout(function () { + onloadCss(link, cb); + }); + }; + function isIE9() { + var doc = getDocument(); + return doc && !!Function('/*@cc_on return (/^9/.test(@_jscript_version) && /MSIE 9.0(?!.*IEMobile)/i.test(navigator.userAgent)); @*/')(); + } + function getDocument() { + if (typeof doneSsr !== 'undefined' && doneSsr.globalDocument) { + return doneSsr.globalDocument; + } + if (typeof document !== 'undefined') { + return document; + } + throw new Error('Unable to load CSS in an environment without a document.'); + } + function getHead() { + var doc = getDocument(); + var head = doc.head || doc.getElementsByTagName('head')[0]; + if (!head) { + var docEl = doc.documentElement || doc; + head = doc.createElement('head'); + docEl.insertBefore(head, docEl.firstChild); + } + return head; + } + function CSSModule(load, loader) { + if (typeof load === 'object') { + this.load = load; + this.loader = loader; + this.address = this.load.address; + this.source = this.load.source; + } else { + this.address = load; + this.source = loader; + } + } + CSSModule.cssCount = 0; + CSSModule.ie9MaxStyleSheets = 31; + CSSModule.currentStyleSheet = null; + CSSModule.prototype = { + injectLink: function () { + if (this._loaded) { + return this._loaded; + } + if (this.linkExists()) { + this._loaded = Promise.resolve(''); + return this._loaded; + } + var doc = getDocument(); + var link = this.link = doc.createElement('link'); + link.type = 'text/css'; + link.rel = 'stylesheet'; + link.href = this.address; + this._loaded = new Promise(function (resolve, reject) { + var timeout = setTimeout(function () { + reject('Unable to load CSS'); + }, waitSeconds * 1000); + var loadCB = function (event) { + clearTimeout(timeout); + link.removeEventListener('load', loadCB); + link.removeEventListener('error', loadCB); + if (event && event.type === 'error') { + reject('Unable to load CSS'); + } else { + resolve(''); + } + }; + if ('isApplicationInstalled' in navigator || !link.addEventListener) { + onloadCss(link, loadCB); + } else if (navigator.noUI) { + loadCB(); + } else { + link.addEventListener('load', loadCB); + link.addEventListener('error', loadCB); + } + getHead().appendChild(link); + }); + return this._loaded; + }, + injectStyle: function () { + var doc = getDocument(); + var head = getHead(); + var style = this.style = doc.createElement('style'); + style.type = 'text/css'; + if (style.sheet) { + style.sheet.cssText = this.source; + } else if (style.styleSheet) { + style.styleSheet.cssText = this.source; + } else { + style.appendChild(doc.createTextNode(this.source)); + } + head.appendChild(style); + }, + ie9StyleSheetLimitHack: function () { + var doc = getDocument(); + if (!CSSModule.cssCount) { + CSSModule.currentStyleSheet = doc.createStyleSheet(); + } + CSSModule.cssCount += 1; + CSSModule.currentStyleSheet.cssText += this.source; + if (CSSModule.cssCount === CSSModule.ie9MaxStyleSheets) { + CSSModule.cssCount = 0; + } + }, + updateURLs: function () { + var rawSource = this.source, address = this.address; + this.source = rawSource.replace(importRegEx, function (whole, part) { + if (isNode) { + return '@import url(' + part + ')'; + } else { + return '@import url(' + steal.joinURIs(address, part) + ')'; + } + }); + if (!loader.isEnv('build')) { + this.source = this.source + '/*# sourceURL=' + address + ' */'; + this.source = this.source.replace(resourceRegEx, function (whole, part) { + return 'url(' + steal.joinURIs(address, part) + ')'; + }); + } + return this.source; + }, + getExistingNode: function () { + var doc = getDocument(); + var selector = '[href=\'' + this.address + '\']'; + return doc.querySelector && doc.querySelector(selector); + }, + linkExists: function () { + var styleSheets = getDocument().styleSheets; + for (var i = 0; i < styleSheets.length; ++i) { + if (this.address === styleSheets[i].href) { + return true; + } + } + return false; + }, + setupLiveReload: function (loader, name) { + var head = getHead(); + var css = this; + if (loader.liveReloadInstalled) { + var cssReload = loader['import']('live-reload', { name: module.id }); + Promise.resolve(cssReload).then(function (reload) { + loader['import'](name).then(function () { + reload.once('!dispose/' + name, function () { + css.style.__isDirty = true; + reload.once('!cycleComplete', function () { + head.removeChild(css.style); + }); + }); + }); + }); + } + } + }; + if (loader.isEnv('production')) { + exports.fetch = function (load) { + var css = new CSSModule(load.address); + return css.injectLink(); + }; + } else { + exports.instantiate = function (load) { + var loader = this; + var css = new CSSModule(load.address, load.source); + load.source = css.updateURLs(); + load.metadata.deps = []; + load.metadata.format = 'css'; + load.metadata.execute = function () { + if (getDocument()) { + if (isIE9()) { + css.ie9StyleSheetLimitHack(); + } else { + css.injectStyle(); + } + css.setupLiveReload(loader, load.name); + } + return loader.newModule({ source: css.source }); + }; + }; + } + exports.CSSModule = CSSModule; + exports.getDocument = getDocument; + exports.getHead = getHead; + exports.locateScheme = true; + exports.buildType = 'css'; + exports.includeInBuild = true; + exports.pluginBuilder = 'steal-css/slim'; + }(function () { + return this; + }(), require, exports, module)); +}); +/*steal-qunit@1.0.2#steal-qunit*/ +'format amd'; +define('steal-qunit@1.0.2#steal-qunit', [ + '@loader', + 'qunitjs/qunit/qunit', + 'qunitjs/qunit/qunit.css' +], function (loader, QUnit) { + if (loader.has('live-reload')) { + setupLiveReload(); + } + setupSauceLabsReporting(); + function setupLiveReload() { + QUnit.done(updateResults); + function findModule(name) { + var mods = QUnit.config.modules; + return mods.filter(function (mod) { + return mod.name === name; + }).pop(); + } + function findTestResult(mod, id) { + var tests = mod.tests || []; + return tests.filter(function (test) { + return test.testId === id; + })[0]; + } + function updateResults() { + var tests = document.getElementById('qunit-tests').children; + var node, id, test, moduleName, mod; + passed = true, removedNodes = []; + for (var i = 0, len = tests.length; i < len; i++) { + node = tests.item(i); + id = node.id.split('-').pop(); + moduleName = node.querySelector('.module-name').textContent; + mod = findModule(moduleName); + test = findTestResult(mod, id); + if (test) { + removeAllButLast(node, 'runtime'); + if (node.hasAttribute && node.hasAttribute('class') && node.className !== 'pass') { + passed = false; + break; + } + } else { + removedNodes.push(node); + } + } + removedNodes.forEach(function (node) { + node.parentNode.removeChild(node); + }); + document.getElementById('qunit-banner').className = passed ? 'qunit-pass' : 'qunit-fail'; + } + function removeAllButLast(parent, className) { + var node, nodes = []; + var children = parent.children; + for (var i = 0, len = children.length; i < len; i++) { + node = children.item(i); + if (node.className === className) + nodes.push(node); + } + while (nodes.length > 1) { + node = nodes.shift(); + parent.removeChild(node); + } + } + } + function setupSauceLabsReporting() { + var log = []; + QUnit.done(function (test_results) { + var tests = []; + for (var i = 0, len = log.length; i < len; i++) { + var details = log[i]; + tests.push({ + name: details.name, + result: details.result, + expected: details.expected, + actual: details.actual, + source: details.source + }); + } + test_results.tests = tests; + window.global_test_results = test_results; + }); + QUnit.testStart(function (testDetails) { + QUnit.log(function (details) { + if (!details.result) { + details.name = testDetails.name; + log.push(details); + } + }); + }); + } + QUnit.config.autorun = false; + steal.done().then(function () { + if (window.Testee && window.Testee.init) { + Testee.init(); + } + QUnit.load(); + }); + return QUnit; +}); +/*can-namespace@1.0.0#can-namespace*/ +define('can-namespace@1.0.0#can-namespace', function (require, exports, module) { + module.exports = {}; +}); +/*can-symbol@1.6.1#can-symbol*/ +define('can-symbol@1.6.1#can-symbol', [ + 'require', + 'exports', + 'module', + 'can-namespace' +], function (require, exports, module) { + (function (global, require, exports, module) { + var namespace = require('can-namespace'); + var CanSymbol; + if (typeof Symbol !== 'undefined' && typeof Symbol.for === 'function') { + CanSymbol = Symbol; + } else { + var symbolNum = 0; + CanSymbol = function CanSymbolPolyfill(description) { + var symbolValue = '@@symbol' + symbolNum++ + description; + var symbol = {}; + Object.defineProperties(symbol, { + toString: { + value: function () { + return symbolValue; + } + } + }); + return symbol; + }; + var descriptionToSymbol = {}; + var symbolToDescription = {}; + CanSymbol.for = function (description) { + var symbol = descriptionToSymbol[description]; + if (!symbol) { + symbol = descriptionToSymbol[description] = CanSymbol(description); + symbolToDescription[symbol] = description; + } + return symbol; + }; + CanSymbol.keyFor = function (symbol) { + return symbolToDescription[symbol]; + }; + [ + 'hasInstance', + 'isConcatSpreadable', + 'iterator', + 'match', + 'prototype', + 'replace', + 'search', + 'species', + 'split', + 'toPrimitive', + 'toStringTag', + 'unscopables' + ].forEach(function (name) { + CanSymbol[name] = CanSymbol('Symbol.' + name); + }); + } + [ + 'isMapLike', + 'isListLike', + 'isValueLike', + 'isFunctionLike', + 'getOwnKeys', + 'getOwnKeyDescriptor', + 'proto', + 'getOwnEnumerableKeys', + 'hasOwnKey', + 'hasKey', + 'size', + 'getName', + 'getIdentity', + 'assignDeep', + 'updateDeep', + 'getValue', + 'setValue', + 'getKeyValue', + 'setKeyValue', + 'updateValues', + 'addValue', + 'removeValues', + 'apply', + 'new', + 'onValue', + 'offValue', + 'onKeyValue', + 'offKeyValue', + 'getKeyDependencies', + 'getValueDependencies', + 'keyHasDependencies', + 'valueHasDependencies', + 'onKeys', + 'onKeysAdded', + 'onKeysRemoved', + 'onPatches' + ].forEach(function (name) { + CanSymbol.for('can.' + name); + }); + module.exports = namespace.Symbol = CanSymbol; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-reflect@1.17.7#reflections/helpers*/ +define('can-reflect@1.17.7#reflections/helpers', [ + 'require', + 'exports', + 'module', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var canSymbol = require('can-symbol'); + module.exports = { + makeGetFirstSymbolValue: function (symbolNames) { + var symbols = symbolNames.map(function (name) { + return canSymbol.for(name); + }); + var length = symbols.length; + return function getFirstSymbol(obj) { + var index = -1; + while (++index < length) { + if (obj[symbols[index]] !== undefined) { + return obj[symbols[index]]; + } + } + }; + }, + hasLength: function (list) { + var type = typeof list; + if (type === 'string' || Array.isArray(list)) { + return true; + } + var length = list && (type !== 'boolean' && type !== 'number' && 'length' in list) && list.length; + return typeof list !== 'function' && (length === 0 || typeof length === 'number' && length > 0 && length - 1 in list); + } + }; +}); +/*can-reflect@1.17.7#reflections/type/type*/ +define('can-reflect@1.17.7#reflections/type/type', [ + 'require', + 'exports', + 'module', + 'can-symbol', + '../helpers' +], function (require, exports, module) { + 'use strict'; + var canSymbol = require('can-symbol'); + var helpers = require('../helpers'); + var plainFunctionPrototypePropertyNames = Object.getOwnPropertyNames(function () { + }.prototype); + var plainFunctionPrototypeProto = Object.getPrototypeOf(function () { + }.prototype); + function isConstructorLike(func) { + var value = func[canSymbol.for('can.new')]; + if (value !== undefined) { + return value; + } + if (typeof func !== 'function') { + return false; + } + var prototype = func.prototype; + if (!prototype) { + return false; + } + if (plainFunctionPrototypeProto !== Object.getPrototypeOf(prototype)) { + return true; + } + var propertyNames = Object.getOwnPropertyNames(prototype); + if (propertyNames.length === plainFunctionPrototypePropertyNames.length) { + for (var i = 0, len = propertyNames.length; i < len; i++) { + if (propertyNames[i] !== plainFunctionPrototypePropertyNames[i]) { + return true; + } + } + return false; + } else { + return true; + } + } + var getNewOrApply = helpers.makeGetFirstSymbolValue([ + 'can.new', + 'can.apply' + ]); + function isFunctionLike(obj) { + var result, symbolValue = !!obj && obj[canSymbol.for('can.isFunctionLike')]; + if (symbolValue !== undefined) { + return symbolValue; + } + result = getNewOrApply(obj); + if (result !== undefined) { + return !!result; + } + return typeof obj === 'function'; + } + function isPrimitive(obj) { + var type = typeof obj; + if (obj == null || type !== 'function' && type !== 'object') { + return true; + } else { + return false; + } + } + var coreHasOwn = Object.prototype.hasOwnProperty; + var funcToString = Function.prototype.toString; + var objectCtorString = funcToString.call(Object); + function isPlainObject(obj) { + if (!obj || typeof obj !== 'object') { + return false; + } + var proto = Object.getPrototypeOf(obj); + if (proto === Object.prototype || proto === null) { + return true; + } + var Constructor = coreHasOwn.call(proto, 'constructor') && proto.constructor; + return typeof Constructor === 'function' && Constructor instanceof Constructor && funcToString.call(Constructor) === objectCtorString; + } + function isBuiltIn(obj) { + if (isPrimitive(obj) || Array.isArray(obj) || isPlainObject(obj) || Object.prototype.toString.call(obj) !== '[object Object]' && Object.prototype.toString.call(obj).indexOf('[object ') !== -1) { + return true; + } else { + return false; + } + } + function isValueLike(obj) { + var symbolValue; + if (isPrimitive(obj)) { + return true; + } + symbolValue = obj[canSymbol.for('can.isValueLike')]; + if (typeof symbolValue !== 'undefined') { + return symbolValue; + } + var value = obj[canSymbol.for('can.getValue')]; + if (value !== undefined) { + return !!value; + } + } + function isMapLike(obj) { + if (isPrimitive(obj)) { + return false; + } + var isMapLike = obj[canSymbol.for('can.isMapLike')]; + if (typeof isMapLike !== 'undefined') { + return !!isMapLike; + } + var value = obj[canSymbol.for('can.getKeyValue')]; + if (value !== undefined) { + return !!value; + } + return true; + } + var onValueSymbol = canSymbol.for('can.onValue'), onKeyValueSymbol = canSymbol.for('can.onKeyValue'), onPatchesSymbol = canSymbol.for('can.onPatches'); + function isObservableLike(obj) { + if (isPrimitive(obj)) { + return false; + } + return Boolean(obj[onValueSymbol] || obj[onKeyValueSymbol] || obj[onPatchesSymbol]); + } + function isListLike(list) { + var symbolValue, type = typeof list; + if (type === 'string') { + return true; + } + if (isPrimitive(list)) { + return false; + } + symbolValue = list[canSymbol.for('can.isListLike')]; + if (typeof symbolValue !== 'undefined') { + return symbolValue; + } + var value = list[canSymbol.iterator]; + if (value !== undefined) { + return !!value; + } + if (Array.isArray(list)) { + return true; + } + return helpers.hasLength(list); + } + var supportsSymbols = typeof Symbol !== 'undefined' && typeof Symbol.for === 'function'; + var isSymbolLike; + if (supportsSymbols) { + isSymbolLike = function (symbol) { + return typeof symbol === 'symbol'; + }; + } else { + var symbolStart = '@@symbol'; + isSymbolLike = function (symbol) { + if (typeof symbol === 'object' && !Array.isArray(symbol)) { + return symbol.toString().substr(0, symbolStart.length) === symbolStart; + } else { + return false; + } + }; + } + module.exports = { + isConstructorLike: isConstructorLike, + isFunctionLike: isFunctionLike, + isListLike: isListLike, + isMapLike: isMapLike, + isObservableLike: isObservableLike, + isPrimitive: isPrimitive, + isBuiltIn: isBuiltIn, + isValueLike: isValueLike, + isSymbolLike: isSymbolLike, + isMoreListLikeThanMapLike: function (obj) { + if (Array.isArray(obj)) { + return true; + } + if (obj instanceof Array) { + return true; + } + if (obj == null) { + return false; + } + var value = obj[canSymbol.for('can.isMoreListLikeThanMapLike')]; + if (value !== undefined) { + return value; + } + var isListLike = this.isListLike(obj), isMapLike = this.isMapLike(obj); + if (isListLike && !isMapLike) { + return true; + } else if (!isListLike && isMapLike) { + return false; + } + }, + isIteratorLike: function (obj) { + return obj && typeof obj === 'object' && typeof obj.next === 'function' && obj.next.length === 0; + }, + isPromise: function (obj) { + return obj instanceof Promise || Object.prototype.toString.call(obj) === '[object Promise]'; + }, + isPlainObject: isPlainObject + }; +}); +/*can-reflect@1.17.7#reflections/call/call*/ +define('can-reflect@1.17.7#reflections/call/call', [ + 'require', + 'exports', + 'module', + 'can-symbol', + '../type/type' +], function (require, exports, module) { + 'use strict'; + var canSymbol = require('can-symbol'); + var typeReflections = require('../type/type'); + module.exports = { + call: function (func, context) { + var args = [].slice.call(arguments, 2); + var apply = func[canSymbol.for('can.apply')]; + if (apply) { + return apply.call(func, context, args); + } else { + return func.apply(context, args); + } + }, + apply: function (func, context, args) { + var apply = func[canSymbol.for('can.apply')]; + if (apply) { + return apply.call(func, context, args); + } else { + return func.apply(context, args); + } + }, + 'new': function (func) { + var args = [].slice.call(arguments, 1); + var makeNew = func[canSymbol.for('can.new')]; + if (makeNew) { + return makeNew.apply(func, args); + } else { + var context = Object.create(func.prototype); + var ret = func.apply(context, args); + if (typeReflections.isPrimitive(ret)) { + return context; + } else { + return ret; + } + } + } + }; +}); +/*can-reflect@1.17.7#reflections/get-set/get-set*/ +define('can-reflect@1.17.7#reflections/get-set/get-set', [ + 'require', + 'exports', + 'module', + 'can-symbol', + '../type/type' +], function (require, exports, module) { + 'use strict'; + var canSymbol = require('can-symbol'); + var typeReflections = require('../type/type'); + var setKeyValueSymbol = canSymbol.for('can.setKeyValue'), getKeyValueSymbol = canSymbol.for('can.getKeyValue'), getValueSymbol = canSymbol.for('can.getValue'), setValueSymbol = canSymbol.for('can.setValue'); + var reflections = { + setKeyValue: function (obj, key, value) { + if (typeReflections.isSymbolLike(key)) { + if (typeof key === 'symbol') { + obj[key] = value; + } else { + Object.defineProperty(obj, key, { + enumerable: false, + configurable: true, + value: value, + writable: true + }); + } + return; + } + var setKeyValue = obj[setKeyValueSymbol]; + if (setKeyValue !== undefined) { + return setKeyValue.call(obj, key, value); + } else { + obj[key] = value; + } + }, + getKeyValue: function (obj, key) { + var getKeyValue = obj[getKeyValueSymbol]; + if (getKeyValue) { + return getKeyValue.call(obj, key); + } + return obj[key]; + }, + deleteKeyValue: function (obj, key) { + var deleteKeyValue = obj[canSymbol.for('can.deleteKeyValue')]; + if (deleteKeyValue) { + return deleteKeyValue.call(obj, key); + } + delete obj[key]; + }, + getValue: function (value) { + if (typeReflections.isPrimitive(value)) { + return value; + } + var getValue = value[getValueSymbol]; + if (getValue) { + return getValue.call(value); + } + return value; + }, + setValue: function (item, value) { + var setValue = item && item[setValueSymbol]; + if (setValue) { + return setValue.call(item, value); + } else { + throw new Error('can-reflect.setValue - Can not set value.'); + } + }, + splice: function (obj, index, removing, adding) { + var howMany; + if (typeof removing !== 'number') { + var updateValues = obj[canSymbol.for('can.updateValues')]; + if (updateValues) { + return updateValues.call(obj, index, removing, adding); + } + howMany = removing.length; + } else { + howMany = removing; + } + if (arguments.length <= 3) { + adding = []; + } + var splice = obj[canSymbol.for('can.splice')]; + if (splice) { + return splice.call(obj, index, howMany, adding); + } + return [].splice.apply(obj, [ + index, + howMany + ].concat(adding)); + }, + addValues: function (obj, adding, index) { + var add = obj[canSymbol.for('can.addValues')]; + if (add) { + return add.call(obj, adding, index); + } + if (Array.isArray(obj) && index === undefined) { + return obj.push.apply(obj, adding); + } + return reflections.splice(obj, index, [], adding); + }, + removeValues: function (obj, removing, index) { + var removeValues = obj[canSymbol.for('can.removeValues')]; + if (removeValues) { + return removeValues.call(obj, removing, index); + } + if (Array.isArray(obj) && index === undefined) { + removing.forEach(function (item) { + var index = obj.indexOf(item); + if (index >= 0) { + obj.splice(index, 1); + } + }); + return; + } + return reflections.splice(obj, index, removing, []); + } + }; + reflections.get = reflections.getKeyValue; + reflections.set = reflections.setKeyValue; + reflections['delete'] = reflections.deleteKeyValue; + module.exports = reflections; +}); +/*can-reflect@1.17.7#reflections/observe/observe*/ +define('can-reflect@1.17.7#reflections/observe/observe', [ + 'require', + 'exports', + 'module', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var canSymbol = require('can-symbol'); + var slice = [].slice; + function makeFallback(symbolName, fallbackName) { + return function (obj, event, handler, queueName) { + var method = obj[canSymbol.for(symbolName)]; + if (method !== undefined) { + return method.call(obj, event, handler, queueName); + } + return this[fallbackName].apply(this, arguments); + }; + } + function makeErrorIfMissing(symbolName, errorMessage) { + return function (obj) { + var method = obj[canSymbol.for(symbolName)]; + if (method !== undefined) { + var args = slice.call(arguments, 1); + return method.apply(obj, args); + } + throw new Error(errorMessage); + }; + } + module.exports = { + onKeyValue: makeFallback('can.onKeyValue', 'onEvent'), + offKeyValue: makeFallback('can.offKeyValue', 'offEvent'), + onKeys: makeErrorIfMissing('can.onKeys', 'can-reflect: can not observe an onKeys event'), + onKeysAdded: makeErrorIfMissing('can.onKeysAdded', 'can-reflect: can not observe an onKeysAdded event'), + onKeysRemoved: makeErrorIfMissing('can.onKeysRemoved', 'can-reflect: can not unobserve an onKeysRemoved event'), + getKeyDependencies: makeErrorIfMissing('can.getKeyDependencies', 'can-reflect: can not determine dependencies'), + getWhatIChange: makeErrorIfMissing('can.getWhatIChange', 'can-reflect: can not determine dependencies'), + getChangesDependencyRecord: function getChangesDependencyRecord(handler) { + var fn = handler[canSymbol.for('can.getChangesDependencyRecord')]; + if (typeof fn === 'function') { + return fn(); + } + }, + keyHasDependencies: makeErrorIfMissing('can.keyHasDependencies', 'can-reflect: can not determine if this has key dependencies'), + onValue: makeErrorIfMissing('can.onValue', 'can-reflect: can not observe value change'), + offValue: makeErrorIfMissing('can.offValue', 'can-reflect: can not unobserve value change'), + getValueDependencies: makeErrorIfMissing('can.getValueDependencies', 'can-reflect: can not determine dependencies'), + valueHasDependencies: makeErrorIfMissing('can.valueHasDependencies', 'can-reflect: can not determine if value has dependencies'), + onPatches: makeErrorIfMissing('can.onPatches', 'can-reflect: can not observe patches on object'), + offPatches: makeErrorIfMissing('can.offPatches', 'can-reflect: can not unobserve patches on object'), + onInstancePatches: makeErrorIfMissing('can.onInstancePatches', 'can-reflect: can not observe onInstancePatches on Type'), + offInstancePatches: makeErrorIfMissing('can.offInstancePatches', 'can-reflect: can not unobserve onInstancePatches on Type'), + onInstanceBoundChange: makeErrorIfMissing('can.onInstanceBoundChange', 'can-reflect: can not observe bound state change in instances.'), + offInstanceBoundChange: makeErrorIfMissing('can.offInstanceBoundChange', 'can-reflect: can not unobserve bound state change'), + isBound: makeErrorIfMissing('can.isBound', 'can-reflect: cannot determine if object is bound'), + onEvent: function (obj, eventName, callback, queue) { + if (obj) { + var onEvent = obj[canSymbol.for('can.onEvent')]; + if (onEvent !== undefined) { + return onEvent.call(obj, eventName, callback, queue); + } else if (obj.addEventListener) { + obj.addEventListener(eventName, callback, queue); + } + } + }, + offEvent: function (obj, eventName, callback, queue) { + if (obj) { + var offEvent = obj[canSymbol.for('can.offEvent')]; + if (offEvent !== undefined) { + return offEvent.call(obj, eventName, callback, queue); + } else if (obj.removeEventListener) { + obj.removeEventListener(eventName, callback, queue); + } + } + }, + setPriority: function (obj, priority) { + if (obj) { + var setPriority = obj[canSymbol.for('can.setPriority')]; + if (setPriority !== undefined) { + setPriority.call(obj, priority); + return true; + } + } + return false; + }, + getPriority: function (obj) { + if (obj) { + var getPriority = obj[canSymbol.for('can.getPriority')]; + if (getPriority !== undefined) { + return getPriority.call(obj); + } + } + return undefined; + } + }; +}); +/*can-reflect@1.17.7#reflections/shape/shape*/ +define('can-reflect@1.17.7#reflections/shape/shape', [ + 'require', + 'exports', + 'module', + 'can-symbol', + '../get-set/get-set', + '../type/type', + '../helpers' +], function (require, exports, module) { + 'use strict'; + var canSymbol = require('can-symbol'); + var getSetReflections = require('../get-set/get-set'); + var typeReflections = require('../type/type'); + var helpers = require('../helpers'); + var getPrototypeOfWorksWithPrimitives = true; + try { + Object.getPrototypeOf(1); + } catch (e) { + getPrototypeOfWorksWithPrimitives = false; + } + var ArrayMap; + if (typeof Map === 'function') { + ArrayMap = Map; + } else { + var isEven = function isEven(num) { + return num % 2 === 0; + }; + ArrayMap = function () { + this.contents = []; + }; + ArrayMap.prototype = { + _getIndex: function (key) { + var idx; + do { + idx = this.contents.indexOf(key, idx); + } while (idx !== -1 && !isEven(idx)); + return idx; + }, + has: function (key) { + return this._getIndex(key) !== -1; + }, + get: function (key) { + var idx = this._getIndex(key); + if (idx !== -1) { + return this.contents[idx + 1]; + } + }, + set: function (key, value) { + var idx = this._getIndex(key); + if (idx !== -1) { + this.contents[idx + 1] = value; + } else { + this.contents.push(key); + this.contents.push(value); + } + }, + 'delete': function (key) { + var idx = this._getIndex(key); + if (idx !== -1) { + this.contents.splice(idx, 2); + } + } + }; + } + var hasOwnProperty = Object.prototype.hasOwnProperty; + var shapeReflections; + var shiftFirstArgumentToThis = function (func) { + return function () { + var args = [this]; + args.push.apply(args, arguments); + return func.apply(null, args); + }; + }; + var getKeyValueSymbol = canSymbol.for('can.getKeyValue'); + var shiftedGetKeyValue = shiftFirstArgumentToThis(getSetReflections.getKeyValue); + var setKeyValueSymbol = canSymbol.for('can.setKeyValue'); + var shiftedSetKeyValue = shiftFirstArgumentToThis(getSetReflections.setKeyValue); + var sizeSymbol = canSymbol.for('can.size'); + var hasUpdateSymbol = helpers.makeGetFirstSymbolValue([ + 'can.updateDeep', + 'can.assignDeep', + 'can.setKeyValue' + ]); + var shouldUpdateOrAssign = function (obj) { + return typeReflections.isPlainObject(obj) || Array.isArray(obj) || !!hasUpdateSymbol(obj); + }; + function isSerializedHelper(obj) { + if (typeReflections.isPrimitive(obj)) { + return true; + } + if (hasUpdateSymbol(obj)) { + return false; + } + return typeReflections.isBuiltIn(obj) && !typeReflections.isPlainObject(obj) && !Array.isArray(obj); + } + var Object_Keys; + try { + Object.keys(1); + Object_Keys = Object.keys; + } catch (e) { + Object_Keys = function (obj) { + if (typeReflections.isPrimitive(obj)) { + return []; + } else { + return Object.keys(obj); + } + }; + } + function createSerializeMap(Type) { + var MapType = Type || ArrayMap; + return { + unwrap: new MapType(), + serialize: new MapType(), + isSerializing: { + unwrap: new MapType(), + serialize: new MapType() + }, + circularReferenceIsSerializing: { + unwrap: new MapType(), + serialize: new MapType() + } + }; + } + function makeSerializer(methodName, symbolsToCheck) { + var serializeMap = null; + function SerializeOperation(MapType) { + this.first = !serializeMap; + if (this.first) { + serializeMap = createSerializeMap(MapType); + } + this.map = serializeMap; + this.result = null; + } + SerializeOperation.prototype.end = function () { + if (this.first) { + serializeMap = null; + } + return this.result; + }; + return function serializer(value, MapType) { + if (isSerializedHelper(value)) { + return value; + } + var operation = new SerializeOperation(MapType); + if (typeReflections.isValueLike(value)) { + operation.result = this[methodName](getSetReflections.getValue(value)); + } else { + var isListLike = typeReflections.isIteratorLike(value) || typeReflections.isMoreListLikeThanMapLike(value); + operation.result = isListLike ? [] : {}; + if (operation.map[methodName].has(value)) { + if (operation.map.isSerializing[methodName].has(value)) { + operation.map.circularReferenceIsSerializing[methodName].set(value, true); + } + return operation.map[methodName].get(value); + } else { + operation.map[methodName].set(value, operation.result); + } + for (var i = 0, len = symbolsToCheck.length; i < len; i++) { + var serializer = value[symbolsToCheck[i]]; + if (serializer) { + operation.map.isSerializing[methodName].set(value, true); + var oldResult = operation.result; + operation.result = serializer.call(value, oldResult); + operation.map.isSerializing[methodName].delete(value); + if (operation.result !== oldResult) { + if (operation.map.circularReferenceIsSerializing[methodName].has(value)) { + operation.end(); + throw new Error('Cannot serialize cirular reference!'); + } + operation.map[methodName].set(value, operation.result); + } + return operation.end(); + } + } + if (typeof obj === 'function') { + operation.map[methodName].set(value, value); + operation.result = value; + } else if (isListLike) { + this.eachIndex(value, function (childValue, index) { + operation.result[index] = this[methodName](childValue); + }, this); + } else { + this.eachKey(value, function (childValue, prop) { + operation.result[prop] = this[methodName](childValue); + }, this); + } + } + return operation.end(); + }; + } + var makeMap; + if (typeof Map !== 'undefined') { + makeMap = function (keys) { + var map = new Map(); + shapeReflections.eachIndex(keys, function (key) { + map.set(key, true); + }); + return map; + }; + } else { + makeMap = function (keys) { + var map = {}; + keys.forEach(function (key) { + map[key] = true; + }); + return { + get: function (key) { + return map[key]; + }, + set: function (key, value) { + map[key] = value; + }, + keys: function () { + return keys; + } + }; + }; + } + var fastHasOwnKey = function (obj) { + var hasOwnKey = obj[canSymbol.for('can.hasOwnKey')]; + if (hasOwnKey) { + return hasOwnKey.bind(obj); + } else { + var map = makeMap(shapeReflections.getOwnEnumerableKeys(obj)); + return function (key) { + return map.get(key); + }; + } + }; + function addPatch(patches, patch) { + var lastPatch = patches[patches.length - 1]; + if (lastPatch) { + if (lastPatch.deleteCount === lastPatch.insert.length && patch.index - lastPatch.index === lastPatch.deleteCount) { + lastPatch.insert.push.apply(lastPatch.insert, patch.insert); + lastPatch.deleteCount += patch.deleteCount; + return; + } + } + patches.push(patch); + } + function updateDeepList(target, source, isAssign) { + var sourceArray = this.toArray(source); + var patches = [], lastIndex = -1; + this.eachIndex(target, function (curVal, index) { + lastIndex = index; + if (index >= sourceArray.length) { + if (!isAssign) { + addPatch(patches, { + index: index, + deleteCount: target.length - index + 1, + insert: [] + }); + } + return false; + } + var newVal = sourceArray[index]; + if (typeReflections.isPrimitive(curVal) || typeReflections.isPrimitive(newVal) || shouldUpdateOrAssign(curVal) === false) { + addPatch(patches, { + index: index, + deleteCount: 1, + insert: [newVal] + }); + } else { + if (isAssign === true) { + this.assignDeep(curVal, newVal); + } else { + this.updateDeep(curVal, newVal); + } + } + }, this); + if (sourceArray.length > lastIndex) { + addPatch(patches, { + index: lastIndex + 1, + deleteCount: 0, + insert: sourceArray.slice(lastIndex + 1) + }); + } + for (var i = 0, patchLen = patches.length; i < patchLen; i++) { + var patch = patches[i]; + getSetReflections.splice(target, patch.index, patch.deleteCount, patch.insert); + } + return target; + } + shapeReflections = { + each: function (obj, callback, context) { + if (typeReflections.isIteratorLike(obj) || typeReflections.isMoreListLikeThanMapLike(obj)) { + return shapeReflections.eachIndex(obj, callback, context); + } else { + return shapeReflections.eachKey(obj, callback, context); + } + }, + eachIndex: function (list, callback, context) { + if (Array.isArray(list)) { + return shapeReflections.eachListLike(list, callback, context); + } else { + var iter, iterator = list[canSymbol.iterator]; + if (typeReflections.isIteratorLike(list)) { + iter = list; + } else if (iterator) { + iter = iterator.call(list); + } + if (iter) { + var res, index = 0; + while (!(res = iter.next()).done) { + if (callback.call(context || list, res.value, index++, list) === false) { + break; + } + } + } else { + shapeReflections.eachListLike(list, callback, context); + } + } + return list; + }, + eachListLike: function (list, callback, context) { + var index = -1; + var length = list.length; + if (length === undefined) { + var size = list[sizeSymbol]; + if (size) { + length = size.call(list); + } else { + throw new Error('can-reflect: unable to iterate.'); + } + } + while (++index < length) { + var item = list[index]; + if (callback.call(context || item, item, index, list) === false) { + break; + } + } + return list; + }, + toArray: function (obj) { + var arr = []; + shapeReflections.each(obj, function (value) { + arr.push(value); + }); + return arr; + }, + eachKey: function (obj, callback, context) { + if (obj) { + var enumerableKeys = shapeReflections.getOwnEnumerableKeys(obj); + var getKeyValue = obj[getKeyValueSymbol] || shiftedGetKeyValue; + return shapeReflections.eachIndex(enumerableKeys, function (key) { + var value = getKeyValue.call(obj, key); + return callback.call(context || obj, value, key, obj); + }); + } + return obj; + }, + 'hasOwnKey': function (obj, key) { + var hasOwnKey = obj[canSymbol.for('can.hasOwnKey')]; + if (hasOwnKey) { + return hasOwnKey.call(obj, key); + } + var getOwnKeys = obj[canSymbol.for('can.getOwnKeys')]; + if (getOwnKeys) { + var found = false; + shapeReflections.eachIndex(getOwnKeys.call(obj), function (objKey) { + if (objKey === key) { + found = true; + return false; + } + }); + return found; + } + return hasOwnProperty.call(obj, key); + }, + getOwnEnumerableKeys: function (obj) { + var getOwnEnumerableKeys = obj[canSymbol.for('can.getOwnEnumerableKeys')]; + if (getOwnEnumerableKeys) { + return getOwnEnumerableKeys.call(obj); + } + if (obj[canSymbol.for('can.getOwnKeys')] && obj[canSymbol.for('can.getOwnKeyDescriptor')]) { + var keys = []; + shapeReflections.eachIndex(shapeReflections.getOwnKeys(obj), function (key) { + var descriptor = shapeReflections.getOwnKeyDescriptor(obj, key); + if (descriptor.enumerable) { + keys.push(key); + } + }, this); + return keys; + } else { + return Object_Keys(obj); + } + }, + getOwnKeys: function (obj) { + var getOwnKeys = obj[canSymbol.for('can.getOwnKeys')]; + if (getOwnKeys) { + return getOwnKeys.call(obj); + } else { + return Object.getOwnPropertyNames(obj); + } + }, + getOwnKeyDescriptor: function (obj, key) { + var getOwnKeyDescriptor = obj[canSymbol.for('can.getOwnKeyDescriptor')]; + if (getOwnKeyDescriptor) { + return getOwnKeyDescriptor.call(obj, key); + } else { + return Object.getOwnPropertyDescriptor(obj, key); + } + }, + unwrap: makeSerializer('unwrap', [canSymbol.for('can.unwrap')]), + serialize: makeSerializer('serialize', [ + canSymbol.for('can.serialize'), + canSymbol.for('can.unwrap') + ]), + assignMap: function (target, source) { + var hasOwnKey = fastHasOwnKey(target); + var getKeyValue = target[getKeyValueSymbol] || shiftedGetKeyValue; + var setKeyValue = target[setKeyValueSymbol] || shiftedSetKeyValue; + shapeReflections.eachKey(source, function (value, key) { + if (!hasOwnKey(key) || getKeyValue.call(target, key) !== value) { + setKeyValue.call(target, key, value); + } + }); + return target; + }, + assignList: function (target, source) { + var inserting = shapeReflections.toArray(source); + getSetReflections.splice(target, 0, inserting, inserting); + return target; + }, + assign: function (target, source) { + if (typeReflections.isIteratorLike(source) || typeReflections.isMoreListLikeThanMapLike(source)) { + shapeReflections.assignList(target, source); + } else { + shapeReflections.assignMap(target, source); + } + return target; + }, + assignDeepMap: function (target, source) { + var hasOwnKey = fastHasOwnKey(target); + var getKeyValue = target[getKeyValueSymbol] || shiftedGetKeyValue; + var setKeyValue = target[setKeyValueSymbol] || shiftedSetKeyValue; + shapeReflections.eachKey(source, function (newVal, key) { + if (!hasOwnKey(key)) { + getSetReflections.setKeyValue(target, key, newVal); + } else { + var curVal = getKeyValue.call(target, key); + if (newVal === curVal) { + } else if (typeReflections.isPrimitive(curVal) || typeReflections.isPrimitive(newVal) || shouldUpdateOrAssign(curVal) === false) { + setKeyValue.call(target, key, newVal); + } else { + shapeReflections.assignDeep(curVal, newVal); + } + } + }, this); + return target; + }, + assignDeepList: function (target, source) { + return updateDeepList.call(this, target, source, true); + }, + assignDeep: function (target, source) { + var assignDeep = target[canSymbol.for('can.assignDeep')]; + if (assignDeep) { + assignDeep.call(target, source); + } else if (typeReflections.isMoreListLikeThanMapLike(source)) { + shapeReflections.assignDeepList(target, source); + } else { + shapeReflections.assignDeepMap(target, source); + } + return target; + }, + updateMap: function (target, source) { + var sourceKeyMap = makeMap(shapeReflections.getOwnEnumerableKeys(source)); + var sourceGetKeyValue = source[getKeyValueSymbol] || shiftedGetKeyValue; + var targetSetKeyValue = target[setKeyValueSymbol] || shiftedSetKeyValue; + shapeReflections.eachKey(target, function (curVal, key) { + if (!sourceKeyMap.get(key)) { + getSetReflections.deleteKeyValue(target, key); + return; + } + sourceKeyMap.set(key, false); + var newVal = sourceGetKeyValue.call(source, key); + if (newVal !== curVal) { + targetSetKeyValue.call(target, key, newVal); + } + }, this); + shapeReflections.eachIndex(sourceKeyMap.keys(), function (key) { + if (sourceKeyMap.get(key)) { + targetSetKeyValue.call(target, key, sourceGetKeyValue.call(source, key)); + } + }); + return target; + }, + updateList: function (target, source) { + var inserting = shapeReflections.toArray(source); + getSetReflections.splice(target, 0, target, inserting); + return target; + }, + update: function (target, source) { + if (typeReflections.isIteratorLike(source) || typeReflections.isMoreListLikeThanMapLike(source)) { + shapeReflections.updateList(target, source); + } else { + shapeReflections.updateMap(target, source); + } + return target; + }, + updateDeepMap: function (target, source) { + var sourceKeyMap = makeMap(shapeReflections.getOwnEnumerableKeys(source)); + var sourceGetKeyValue = source[getKeyValueSymbol] || shiftedGetKeyValue; + var targetSetKeyValue = target[setKeyValueSymbol] || shiftedSetKeyValue; + shapeReflections.eachKey(target, function (curVal, key) { + if (!sourceKeyMap.get(key)) { + getSetReflections.deleteKeyValue(target, key); + return; + } + sourceKeyMap.set(key, false); + var newVal = sourceGetKeyValue.call(source, key); + if (typeReflections.isPrimitive(curVal) || typeReflections.isPrimitive(newVal) || shouldUpdateOrAssign(curVal) === false) { + targetSetKeyValue.call(target, key, newVal); + } else { + shapeReflections.updateDeep(curVal, newVal); + } + }, this); + shapeReflections.eachIndex(sourceKeyMap.keys(), function (key) { + if (sourceKeyMap.get(key)) { + targetSetKeyValue.call(target, key, sourceGetKeyValue.call(source, key)); + } + }); + return target; + }, + updateDeepList: function (target, source) { + return updateDeepList.call(this, target, source); + }, + updateDeep: function (target, source) { + var updateDeep = target[canSymbol.for('can.updateDeep')]; + if (updateDeep) { + updateDeep.call(target, source); + } else if (typeReflections.isMoreListLikeThanMapLike(source)) { + shapeReflections.updateDeepList(target, source); + } else { + shapeReflections.updateDeepMap(target, source); + } + return target; + }, + hasKey: function (obj, key) { + if (obj == null) { + return false; + } + if (typeReflections.isPrimitive(obj)) { + if (hasOwnProperty.call(obj, key)) { + return true; + } else { + var proto; + if (getPrototypeOfWorksWithPrimitives) { + proto = Object.getPrototypeOf(obj); + } else { + proto = obj.__proto__; + } + if (proto !== undefined) { + return key in proto; + } else { + return obj[key] !== undefined; + } + } + } + var hasKey = obj[canSymbol.for('can.hasKey')]; + if (hasKey) { + return hasKey.call(obj, key); + } + var found = shapeReflections.hasOwnKey(obj, key); + return found || key in obj; + }, + getAllEnumerableKeys: function () { + }, + getAllKeys: function () { + }, + assignSymbols: function (target, source) { + shapeReflections.eachKey(source, function (value, key) { + var symbol = typeReflections.isSymbolLike(canSymbol[key]) ? canSymbol[key] : canSymbol.for(key); + getSetReflections.setKeyValue(target, symbol, value); + }); + return target; + }, + isSerialized: isSerializedHelper, + size: function (obj) { + if (obj == null) { + return 0; + } + var size = obj[sizeSymbol]; + var count = 0; + if (size) { + return size.call(obj); + } else if (helpers.hasLength(obj)) { + return obj.length; + } else if (typeReflections.isListLike(obj)) { + shapeReflections.eachIndex(obj, function () { + count++; + }); + return count; + } else if (obj) { + return shapeReflections.getOwnEnumerableKeys(obj).length; + } else { + return undefined; + } + }, + defineInstanceKey: function (cls, key, properties) { + var defineInstanceKey = cls[canSymbol.for('can.defineInstanceKey')]; + if (defineInstanceKey) { + return defineInstanceKey.call(cls, key, properties); + } + var proto = cls.prototype; + defineInstanceKey = proto[canSymbol.for('can.defineInstanceKey')]; + if (defineInstanceKey) { + defineInstanceKey.call(proto, key, properties); + } else { + Object.defineProperty(proto, key, shapeReflections.assign({ + configurable: true, + enumerable: !typeReflections.isSymbolLike(key), + writable: true + }, properties)); + } + } + }; + shapeReflections.isSerializable = shapeReflections.isSerialized; + shapeReflections.keys = shapeReflections.getOwnEnumerableKeys; + module.exports = shapeReflections; +}); +/*can-reflect@1.17.7#reflections/shape/schema/schema*/ +define('can-reflect@1.17.7#reflections/shape/schema/schema', [ + 'require', + 'exports', + 'module', + 'can-symbol', + '../../type/type', + '../../get-set/get-set', + '../shape' +], function (require, exports, module) { + 'use strict'; + var canSymbol = require('can-symbol'); + var typeReflections = require('../../type/type'); + var getSetReflections = require('../../get-set/get-set'); + var shapeReflections = require('../shape'); + var getSchemaSymbol = canSymbol.for('can.getSchema'), isMemberSymbol = canSymbol.for('can.isMember'), newSymbol = canSymbol.for('can.new'); + function comparator(a, b) { + return a.localeCompare(b); + } + function sort(obj) { + if (typeReflections.isPrimitive(obj)) { + return obj; + } + var out; + if (typeReflections.isListLike(obj)) { + out = []; + shapeReflections.eachKey(obj, function (item) { + out.push(sort(item)); + }); + return out; + } + if (typeReflections.isMapLike(obj)) { + out = {}; + shapeReflections.getOwnKeys(obj).sort(comparator).forEach(function (key) { + out[key] = sort(getSetReflections.getKeyValue(obj, key)); + }); + return out; + } + return obj; + } + function isPrimitiveConverter(Type) { + return Type === Number || Type === String || Type === Boolean; + } + var schemaReflections = { + getSchema: function (type) { + if (type === undefined) { + return undefined; + } + var getSchema = type[getSchemaSymbol]; + if (getSchema === undefined) { + type = type.constructor; + getSchema = type && type[getSchemaSymbol]; + } + return getSchema !== undefined ? getSchema.call(type) : undefined; + }, + getIdentity: function (value, schema) { + schema = schema || schemaReflections.getSchema(value); + if (schema === undefined) { + throw new Error('can-reflect.getIdentity - Unable to find a schema for the given value.'); + } + var identity = schema.identity; + if (!identity || identity.length === 0) { + throw new Error('can-reflect.getIdentity - Provided schema lacks an identity property.'); + } else if (identity.length === 1) { + return getSetReflections.getKeyValue(value, identity[0]); + } else { + var id = {}; + identity.forEach(function (key) { + id[key] = getSetReflections.getKeyValue(value, key); + }); + return JSON.stringify(schemaReflections.cloneKeySort(id)); + } + }, + cloneKeySort: function (obj) { + return sort(obj); + }, + convert: function (value, Type) { + if (isPrimitiveConverter(Type)) { + return Type(value); + } + var isMemberTest = Type[isMemberSymbol], isMember = false, type = typeof Type, createNew = Type[newSymbol]; + if (isMemberTest !== undefined) { + isMember = isMemberTest.call(Type, value); + } else if (type === 'function') { + if (typeReflections.isConstructorLike(Type)) { + isMember = value instanceof Type; + } + } + if (isMember) { + return value; + } + if (createNew !== undefined) { + return createNew.call(Type, value); + } else if (type === 'function') { + if (typeReflections.isConstructorLike(Type)) { + return new Type(value); + } else { + return Type(value); + } + } else { + throw new Error('can-reflect: Can not convert values into type. Type must provide `can.new` symbol.'); + } + } + }; + module.exports = schemaReflections; +}); +/*can-reflect@1.17.7#reflections/get-name/get-name*/ +define('can-reflect@1.17.7#reflections/get-name/get-name', [ + 'require', + 'exports', + 'module', + 'can-symbol', + '../type/type' +], function (require, exports, module) { + 'use strict'; + var canSymbol = require('can-symbol'); + var typeReflections = require('../type/type'); + var getNameSymbol = canSymbol.for('can.getName'); + function setName(obj, nameGetter) { + if (typeof nameGetter !== 'function') { + var value = nameGetter; + nameGetter = function () { + return value; + }; + } + Object.defineProperty(obj, getNameSymbol, { value: nameGetter }); + } + var anonymousID = 0; + function getName(obj) { + var type = typeof obj; + if (obj === null || type !== 'object' && type !== 'function') { + return '' + obj; + } + var nameGetter = obj[getNameSymbol]; + if (nameGetter) { + return nameGetter.call(obj); + } + if (type === 'function') { + if (!('name' in obj)) { + obj.name = 'functionIE' + anonymousID++; + } + return obj.name; + } + if (obj.constructor && obj !== obj.constructor) { + var parent = getName(obj.constructor); + if (parent) { + if (typeReflections.isValueLike(obj)) { + return parent + '<>'; + } + if (typeReflections.isMoreListLikeThanMapLike(obj)) { + return parent + '[]'; + } + if (typeReflections.isMapLike(obj)) { + return parent + '{}'; + } + } + } + return undefined; + } + module.exports = { + setName: setName, + getName: getName + }; +}); +/*can-reflect@1.17.7#types/map*/ +define('can-reflect@1.17.7#types/map', [ + 'require', + 'exports', + 'module', + '../reflections/shape/shape', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var shape = require('../reflections/shape/shape'); + var CanSymbol = require('can-symbol'); + function keysPolyfill() { + var keys = []; + var currentIndex = 0; + this.forEach(function (val, key) { + keys.push(key); + }); + return { + next: function () { + return { + value: keys[currentIndex], + done: currentIndex++ === keys.length + }; + } + }; + } + if (typeof Map !== 'undefined') { + shape.assignSymbols(Map.prototype, { + 'can.getOwnEnumerableKeys': Map.prototype.keys, + 'can.setKeyValue': Map.prototype.set, + 'can.getKeyValue': Map.prototype.get, + 'can.deleteKeyValue': Map.prototype['delete'], + 'can.hasOwnKey': Map.prototype.has + }); + if (typeof Map.prototype.keys !== 'function') { + Map.prototype.keys = Map.prototype[CanSymbol.for('can.getOwnEnumerableKeys')] = keysPolyfill; + } + } + if (typeof WeakMap !== 'undefined') { + shape.assignSymbols(WeakMap.prototype, { + 'can.getOwnEnumerableKeys': function () { + throw new Error('can-reflect: WeakMaps do not have enumerable keys.'); + }, + 'can.setKeyValue': WeakMap.prototype.set, + 'can.getKeyValue': WeakMap.prototype.get, + 'can.deleteKeyValue': WeakMap.prototype['delete'], + 'can.hasOwnKey': WeakMap.prototype.has + }); + } +}); +/*can-reflect@1.17.7#types/set*/ +define('can-reflect@1.17.7#types/set', [ + 'require', + 'exports', + 'module', + '../reflections/shape/shape', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var shape = require('../reflections/shape/shape'); + var CanSymbol = require('can-symbol'); + if (typeof Set !== 'undefined') { + shape.assignSymbols(Set.prototype, { + 'can.isMoreListLikeThanMapLike': true, + 'can.updateValues': function (index, removing, adding) { + if (removing !== adding) { + shape.each(removing, function (value) { + this.delete(value); + }, this); + } + shape.each(adding, function (value) { + this.add(value); + }, this); + }, + 'can.size': function () { + return this.size; + } + }); + if (typeof Set.prototype[CanSymbol.iterator] !== 'function') { + Set.prototype[CanSymbol.iterator] = function () { + var arr = []; + var currentIndex = 0; + this.forEach(function (val) { + arr.push(val); + }); + return { + next: function () { + return { + value: arr[currentIndex], + done: currentIndex++ === arr.length + }; + } + }; + }; + } + } + if (typeof WeakSet !== 'undefined') { + shape.assignSymbols(WeakSet.prototype, { + 'can.isListLike': true, + 'can.isMoreListLikeThanMapLike': true, + 'can.updateValues': function (index, removing, adding) { + if (removing !== adding) { + shape.each(removing, function (value) { + this.delete(value); + }, this); + } + shape.each(adding, function (value) { + this.add(value); + }, this); + }, + 'can.size': function () { + throw new Error('can-reflect: WeakSets do not have enumerable keys.'); + } + }); + } +}); +/*can-reflect@1.17.7#can-reflect*/ +define('can-reflect@1.17.7#can-reflect', [ + 'require', + 'exports', + 'module', + './reflections/call/call', + './reflections/get-set/get-set', + './reflections/observe/observe', + './reflections/shape/shape', + './reflections/shape/schema/schema', + './reflections/type/type', + './reflections/get-name/get-name', + 'can-namespace', + './types/map', + './types/set' +], function (require, exports, module) { + 'use strict'; + var functionReflections = require('./reflections/call/call'); + var getSet = require('./reflections/get-set/get-set'); + var observe = require('./reflections/observe/observe'); + var shape = require('./reflections/shape/shape'); + var schema = require('./reflections/shape/schema/schema'); + var type = require('./reflections/type/type'); + var getName = require('./reflections/get-name/get-name'); + var namespace = require('can-namespace'); + var reflect = {}; + [ + functionReflections, + getSet, + observe, + shape, + type, + getName, + schema + ].forEach(function (reflections) { + for (var prop in reflections) { + reflect[prop] = reflections[prop]; + } + }); + require('./types/map'); + require('./types/set'); + module.exports = namespace.Reflect = reflect; +}); +/*can-globals@1.2.0#can-globals-proto*/ +define('can-globals@1.2.0#can-globals-proto', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + function dispatch(key) { + var handlers = this.eventHandlers[key]; + if (handlers) { + var handlersCopy = handlers.slice(); + var value = this.getKeyValue(key); + for (var i = 0; i < handlersCopy.length; i++) { + handlersCopy[i](value); + } + } + } + function Globals() { + this.eventHandlers = {}; + this.properties = {}; + } + Globals.prototype.define = function (key, value, enableCache) { + if (enableCache === undefined) { + enableCache = true; + } + if (!this.properties[key]) { + this.properties[key] = { + default: value, + value: value, + enableCache: enableCache + }; + } + return this; + }; + Globals.prototype.getKeyValue = function (key) { + var property = this.properties[key]; + if (property) { + if (typeof property.value === 'function') { + if (property.cachedValue) { + return property.cachedValue; + } + if (property.enableCache) { + property.cachedValue = property.value(); + return property.cachedValue; + } else { + return property.value(); + } + } + return property.value; + } + }; + Globals.prototype.makeExport = function (key) { + return function (value) { + if (arguments.length === 0) { + return this.getKeyValue(key); + } + if (typeof value === 'undefined' || value === null) { + this.deleteKeyValue(key); + } else { + if (typeof value === 'function') { + this.setKeyValue(key, function () { + return value; + }); + } else { + this.setKeyValue(key, value); + } + return value; + } + }.bind(this); + }; + Globals.prototype.offKeyValue = function (key, handler) { + if (this.properties[key]) { + var handlers = this.eventHandlers[key]; + if (handlers) { + var i = handlers.indexOf(handler); + handlers.splice(i, 1); + } + } + return this; + }; + Globals.prototype.onKeyValue = function (key, handler) { + if (this.properties[key]) { + if (!this.eventHandlers[key]) { + this.eventHandlers[key] = []; + } + this.eventHandlers[key].push(handler); + } + return this; + }; + Globals.prototype.deleteKeyValue = function (key) { + var property = this.properties[key]; + if (property !== undefined) { + property.value = property.default; + property.cachedValue = undefined; + dispatch.call(this, key); + } + return this; + }; + Globals.prototype.setKeyValue = function (key, value) { + if (!this.properties[key]) { + return this.define(key, value); + } + var property = this.properties[key]; + property.value = value; + property.cachedValue = undefined; + dispatch.call(this, key); + return this; + }; + Globals.prototype.reset = function () { + for (var key in this.properties) { + if (this.properties.hasOwnProperty(key)) { + this.properties[key].value = this.properties[key].default; + this.properties[key].cachedValue = undefined; + dispatch.call(this, key); + } + } + return this; + }; + canReflect.assignSymbols(Globals.prototype, { + 'can.getKeyValue': Globals.prototype.getKeyValue, + 'can.setKeyValue': Globals.prototype.setKeyValue, + 'can.deleteKeyValue': Globals.prototype.deleteKeyValue, + 'can.onKeyValue': Globals.prototype.onKeyValue, + 'can.offKeyValue': Globals.prototype.offKeyValue + }); + module.exports = Globals; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-globals@1.2.0#can-globals-instance*/ +define('can-globals@1.2.0#can-globals-instance', [ + 'require', + 'exports', + 'module', + 'can-namespace', + './can-globals-proto' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + var Globals = require('./can-globals-proto'); + var globals = new Globals(); + if (namespace.globals) { + throw new Error('You can\'t have two versions of can-globals, check your dependencies'); + } else { + module.exports = namespace.globals = globals; + } + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-globals@1.2.0#global/global*/ +define('can-globals@1.2.0#global/global', [ + 'require', + 'exports', + 'module', + 'can-globals/can-globals-instance' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var globals = require('can-globals/can-globals-instance'); + globals.define('global', function () { + return typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope ? self : typeof process === 'object' && {}.toString.call(process) === '[object process]' ? global : window; + }); + module.exports = globals.makeExport('global'); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-globals@1.2.0#mutation-observer/mutation-observer*/ +define('can-globals@1.2.0#mutation-observer/mutation-observer', [ + 'require', + 'exports', + 'module', + 'can-globals/global/global', + 'can-globals/can-globals-instance' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + require('can-globals/global/global'); + var globals = require('can-globals/can-globals-instance'); + globals.define('MutationObserver', function () { + var GLOBAL = globals.getKeyValue('global'); + return GLOBAL.MutationObserver || GLOBAL.WebKitMutationObserver || GLOBAL.MozMutationObserver; + }); + module.exports = globals.makeExport('MutationObserver'); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-globals@1.2.0#document/document*/ +define('can-globals@1.2.0#document/document', [ + 'require', + 'exports', + 'module', + 'can-globals/global/global', + 'can-globals/can-globals-instance' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + require('can-globals/global/global'); + var globals = require('can-globals/can-globals-instance'); + globals.define('document', function () { + return globals.getKeyValue('global').document; + }); + module.exports = globals.makeExport('document'); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-globals@1.2.0#location/location*/ +define('can-globals@1.2.0#location/location', [ + 'require', + 'exports', + 'module', + 'can-globals/global/global', + 'can-globals/can-globals-instance' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + require('can-globals/global/global'); + var globals = require('can-globals/can-globals-instance'); + globals.define('location', function () { + return globals.getKeyValue('global').location; + }); + module.exports = globals.makeExport('location'); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-globals@1.2.0#is-node/is-node*/ +define('can-globals@1.2.0#is-node/is-node', [ + 'require', + 'exports', + 'module', + 'can-globals/can-globals-instance' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var globals = require('can-globals/can-globals-instance'); + globals.define('isNode', function () { + return typeof process === 'object' && {}.toString.call(process) === '[object process]'; + }); + module.exports = globals.makeExport('isNode'); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-globals@1.2.0#is-browser-window/is-browser-window*/ +define('can-globals@1.2.0#is-browser-window/is-browser-window', [ + 'require', + 'exports', + 'module', + 'can-globals/can-globals-instance', + '../is-node/is-node' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var globals = require('can-globals/can-globals-instance'); + require('../is-node/is-node'); + globals.define('isBrowserWindow', function () { + var isNode = globals.getKeyValue('isNode'); + return typeof window !== 'undefined' && typeof document !== 'undefined' && isNode === false; + }); + module.exports = globals.makeExport('isBrowserWindow'); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-globals@1.2.0#custom-elements/custom-elements*/ +define('can-globals@1.2.0#custom-elements/custom-elements', [ + 'require', + 'exports', + 'module', + 'can-globals/global/global', + 'can-globals/can-globals-instance' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + require('can-globals/global/global'); + var globals = require('can-globals/can-globals-instance'); + globals.define('customElements', function () { + var GLOBAL = globals.getKeyValue('global'); + return GLOBAL.customElements; + }); + module.exports = globals.makeExport('customElements'); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-globals@1.2.0#can-globals*/ +define('can-globals@1.2.0#can-globals', [ + 'require', + 'exports', + 'module', + 'can-globals/can-globals-instance', + './global/global', + './document/document', + './location/location', + './mutation-observer/mutation-observer', + './is-browser-window/is-browser-window', + './is-node/is-node', + './custom-elements/custom-elements' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var globals = require('can-globals/can-globals-instance'); + require('./global/global'); + require('./document/document'); + require('./location/location'); + require('./mutation-observer/mutation-observer'); + require('./is-browser-window/is-browser-window'); + require('./is-node/is-node'); + require('./custom-elements/custom-elements'); + module.exports = globals; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-simple-dom@1.4.2#lib/document/node*/ +define('can-simple-dom@1.4.2#lib/document/node', function (require, exports, module) { + function Node(nodeType, nodeName, nodeValue, ownerDocument) { + this.nodeType = nodeType; + this.nodeName = nodeName; + this.nodeValue = nodeValue; + this.ownerDocument = ownerDocument; + this.childNodes = new ChildNodes(this); + this.parentNode = null; + this.previousSibling = null; + this.nextSibling = null; + this.firstChild = null; + this.lastChild = null; + } + Node.prototype._cloneNode = function () { + return new Node(this.nodeType, this.nodeName, this.nodeValue, this.ownerDocument); + }; + Node.prototype.cloneNode = function (deep) { + var node = this._cloneNode(); + if (deep) { + var child = this.firstChild, nextChild = child; + while (nextChild) { + nextChild = child.nextSibling; + nodeAppendChild.call(node, child.cloneNode(true)); + child = nextChild; + } + } + return node; + }; + var nodeAppendChild = Node.prototype.appendChild = function (node) { + if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { + insertFragment(node, this, this.lastChild, null); + return node; + } + if (node.parentNode) { + nodeRemoveChild.call(node.parentNode, node); + } + node.parentNode = this; + var refNode = this.lastChild; + if (refNode === null) { + this.firstChild = node; + this.lastChild = node; + } else { + node.previousSibling = refNode; + refNode.nextSibling = node; + this.lastChild = node; + } + ensureOwnerDocument(this, node); + return node; + }; + function insertFragment(fragment, newParent, before, after) { + if (!fragment.firstChild) { + return; + } + var firstChild = fragment.firstChild; + var lastChild = firstChild; + var node = firstChild; + firstChild.previousSibling = before; + if (before) { + before.nextSibling = firstChild; + } else { + newParent.firstChild = firstChild; + } + while (node) { + node.parentNode = newParent; + ensureOwnerDocument(newParent, node); + lastChild = node; + node = node.nextSibling; + } + lastChild.nextSibling = after; + if (after) { + after.previousSibling = lastChild; + } else { + newParent.lastChild = lastChild; + } + fragment.firstChild = null; + fragment.lastChild = null; + } + function ensureOwnerDocument(parent, child) { + var ownerDocument = parent.nodeType === 9 ? parent : parent.ownerDocument; + if (parent.ownerDocument !== child.ownerDocument) { + var node = child; + while (node) { + node.ownerDocument = ownerDocument; + if (node.firstChild) { + ensureOwnerDocument(node, node.firstChild); + } + node = node.nextSibling; + } + } + } + var nodeInsertBefore = Node.prototype.insertBefore = function (node, refNode) { + if (refNode == null) { + return nodeAppendChild.call(this, node); + } + if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { + insertFragment(node, this, refNode ? refNode.previousSibling : null, refNode); + return node; + } + if (node.parentNode) { + nodeRemoveChild.call(node.parentNode, node); + } + node.parentNode = this; + var previousSibling = refNode.previousSibling; + if (previousSibling) { + previousSibling.nextSibling = node; + node.previousSibling = previousSibling; + } + refNode.previousSibling = node; + node.nextSibling = refNode; + if (this.firstChild === refNode) { + this.firstChild = node; + } + ensureOwnerDocument(this, node); + return node; + }; + var nodeRemoveChild = Node.prototype.removeChild = function (refNode) { + if (this.firstChild === refNode) { + this.firstChild = refNode.nextSibling; + } + if (this.lastChild === refNode) { + this.lastChild = refNode.previousSibling; + } + if (refNode.previousSibling) { + refNode.previousSibling.nextSibling = refNode.nextSibling; + } + if (refNode.nextSibling) { + refNode.nextSibling.previousSibling = refNode.previousSibling; + } + refNode.parentNode = null; + refNode.nextSibling = null; + refNode.previousSibling = null; + return refNode; + }; + Node.prototype.replaceChild = function (newChild, oldChild) { + nodeInsertBefore.call(this, newChild, oldChild); + nodeRemoveChild.call(this, oldChild); + return oldChild; + }; + Node.prototype.contains = function (child) { + child = child.parentNode; + while (child) { + if (child === this) { + return true; + } + child = child.parentNode; + } + return false; + }; + Node.prototype.addEventListener = function () { + }; + Node.prototype.removeEventListener = function () { + }; + Node.ELEMENT_NODE = 1; + Node.ATTRIBUTE_NODE = 2; + Node.TEXT_NODE = 3; + Node.CDATA_SECTION_NODE = 4; + Node.ENTITY_REFERENCE_NODE = 5; + Node.ENTITY_NODE = 6; + Node.PROCESSING_INSTRUCTION_NODE = 7; + Node.COMMENT_NODE = 8; + Node.DOCUMENT_NODE = 9; + Node.DOCUMENT_TYPE_NODE = 10; + Node.DOCUMENT_FRAGMENT_NODE = 11; + Node.NOTATION_NODE = 12; + function ChildNodes(node) { + this.node = node; + } + ChildNodes.prototype.item = function (index) { + var child = this.node.firstChild; + for (var i = 0; child && index !== i; i++) { + child = child.nextSibling; + } + return child; + }; + exports.Node = Node; + exports.nodeRemoveChild = nodeRemoveChild; +}); +/*can-simple-dom@1.4.2#lib/document/style*/ +define('can-simple-dom@1.4.2#lib/document/style', function (require, exports, module) { + function CSSStyleDeclaration(node) { + this.__node = node; + } + CSSStyleDeclaration.prototype.getPropertyValue = function () { + }; + Object.defineProperty(CSSStyleDeclaration.prototype, 'cssText', { + enumerable: true, + configurable: true, + get: function () { + return this.__node.getAttribute('style') || ''; + }, + set: function (val) { + this.__node._setAttribute('style', val); + } + }); + module.exports = CSSStyleDeclaration; +}); +/*can-simple-dom@1.4.2#lib/document/element*/ +define('can-simple-dom@1.4.2#lib/document/element', [ + 'require', + 'exports', + 'module', + './node', + './style' +], function (require, exports, module) { + var _node = require('./node'); + var nodeRemoveChild = _node.nodeRemoveChild; + var Node = _node.Node; + var CSSStyleDeclaration = require('./style'); + let attrSpecial = { + 'class': function (element, value) { + element._className = value; + } + }; + function Element(tagName, ownerDocument) { + tagName = tagName.toUpperCase(); + this.nodeConstructor(1, tagName, null, ownerDocument); + this.style = new CSSStyleDeclaration(this); + this.attributes = []; + this.tagName = tagName; + } + Element.prototype = Object.create(Node.prototype); + Element.prototype.constructor = Element; + Element.prototype.nodeConstructor = Node; + Element.prototype._cloneNode = function () { + var node = this.ownerDocument.createElement(this.tagName); + node.attributes = this.attributes.map(function (attr) { + return { + name: attr.name, + value: attr.value, + specified: attr.specified + }; + }); + return node; + }; + Element.prototype.getAttribute = function (_name) { + var attributes = this.attributes; + var name = _name.toLowerCase(); + var attr; + for (var i = 0, l = attributes.length; i < l; i++) { + attr = attributes[i]; + if (attr.name === name) { + return attr.value; + } + } + return null; + }; + Element.prototype.setAttribute = function () { + return this._setAttribute.apply(this, arguments); + }; + Element.prototype._setAttribute = function (_name, value) { + value += ''; + var attributes = this.attributes; + var name = _name.toLowerCase(); + var attr; + for (var i = 0, l = attributes.length; i < l; i++) { + attr = attributes[i]; + if (attr.name === name) { + attr.value = value; + const special = attrSpecial[name]; + if (special) { + special(this, value); + } + return; + } + } + attributes.push({ + name: name, + value: value, + specified: true + }); + attributes[name] = value; + const special = attrSpecial[name]; + if (special) { + special(this, value); + } + }; + Element.prototype.hasAttribute = function (_name) { + var attributes = this.attributes; + var name = _name.toLowerCase(); + var attr; + for (var i = 0, len = attributes.length; i < len; i++) { + attr = attributes[i]; + if (attr.name === name) { + return true; + } + } + return false; + }; + Element.prototype.removeAttribute = function (name) { + var attributes = this.attributes; + for (var i = 0, l = attributes.length; i < l; i++) { + var attr = attributes[i]; + if (attr.name === name) { + attributes.splice(i, 1); + const special = attrSpecial[name]; + if (special) { + special(this, undefined); + } + delete attributes[name]; + return; + } + } + }; + Element.prototype.getElementsByTagName = function (name) { + name = name.toUpperCase(); + var elements = []; + var cur = this.firstChild; + while (cur) { + if (cur.nodeType === Node.ELEMENT_NODE) { + if (cur.nodeName === name || name === '*') { + elements.push(cur); + } + elements.push.apply(elements, cur.getElementsByTagName(name)); + } + cur = cur.nextSibling; + } + return elements; + }; + Element.prototype.getElementById = function (id) { + var cur = this.firstChild, child; + while (cur) { + if (cur.attributes && cur.attributes.length) { + var attr; + for (var i = 0, len = cur.attributes.length; i < len; i++) { + attr = cur.attributes[i]; + if (attr.name === 'id' && attr.value === id) { + return cur; + } + } + } + if (cur.getElementById) { + child = cur.getElementById(id); + if (child) { + return child; + } + } + cur = cur.nextSibling; + } + }; + function Style(node) { + this.__node = node; + } + if (Object.defineProperty) { + Object.defineProperty(Element.prototype, 'className', { + configurable: true, + enumerable: true, + get: function () { + return this._className || ''; + }, + set: function (val) { + this._setAttribute('class', val); + this._className = val; + } + }); + Object.defineProperty(Element.prototype, 'innerHTML', { + configurable: true, + enumerable: true, + get: function () { + var html = ''; + var cur = this.firstChild; + while (cur) { + html += this.ownerDocument.__serializer.serialize(cur); + cur = cur.nextSibling; + } + return html; + }, + set: function (html) { + this.lastChild = this.firstChild = null; + var fragment; + if (this.nodeName === 'SCRIPT' || this.nodeName === 'STYLE') { + fragment = this.ownerDocument.createTextNode(html); + } else { + fragment = this.ownerDocument.__parser.parse(html); + } + this.appendChild(fragment); + } + }); + Object.defineProperty(Element.prototype, 'outerHTML', { + get: function () { + return this.ownerDocument.__serializer.serialize(this); + }, + set: function (html) { + this.parentNode.replaceChild(this.ownerDocument.__parser.parse(html), this); + } + }); + Object.defineProperty(Element.prototype, 'textContent', { + get: function () { + var fc = this.firstChild; + return fc && fc.nodeValue || ''; + }, + set: function (val) { + while (this.firstChild) { + nodeRemoveChild.call(this, this.firstChild); + } + var tn = this.ownerDocument.createTextNode(val); + this.appendChild(tn); + } + }); + } + module.exports = Element; +}); +/*can-simple-dom@1.4.2#lib/document/text*/ +define('can-simple-dom@1.4.2#lib/document/text', [ + 'require', + 'exports', + 'module', + './node' +], function (require, exports, module) { + var Node = require('./node').Node; + function Text(text, ownerDocument) { + this.nodeConstructor(3, '#text', text, ownerDocument); + } + Text.prototype._cloneNode = function () { + return this.ownerDocument.createTextNode(this.nodeValue); + }; + Text.prototype = Object.create(Node.prototype); + Text.prototype.constructor = Text; + Text.prototype.nodeConstructor = Node; + module.exports = Text; +}); +/*can-simple-dom@1.4.2#lib/document/comment*/ +define('can-simple-dom@1.4.2#lib/document/comment', [ + 'require', + 'exports', + 'module', + './node' +], function (require, exports, module) { + var Node = require('./node').Node; + function Comment(text, ownerDocument) { + this.nodeConstructor(8, '#comment', text, ownerDocument); + } + Comment.prototype._cloneNode = function () { + return this.ownerDocument.createComment(this.nodeValue); + }; + Comment.prototype = Object.create(Node.prototype); + Comment.prototype.constructor = Comment; + Comment.prototype.nodeConstructor = Node; + module.exports = Comment; +}); +/*can-simple-dom@1.4.2#lib/document/document-fragment*/ +define('can-simple-dom@1.4.2#lib/document/document-fragment', [ + 'require', + 'exports', + 'module', + './node' +], function (require, exports, module) { + var Node = require('./node').Node; + function DocumentFragment(ownerDocument) { + this.nodeConstructor(11, '#document-fragment', null, ownerDocument); + } + DocumentFragment.prototype._cloneNode = function () { + return this.ownerDocument.createDocumentFragment(); + }; + DocumentFragment.prototype = Object.create(Node.prototype); + DocumentFragment.prototype.constructor = DocumentFragment; + DocumentFragment.prototype.nodeConstructor = Node; + module.exports = DocumentFragment; +}); +/*micro-location@0.1.5#lib/micro-location*/ +function Location() { + this.init.apply(this, arguments); +} +Location.prototype = { + init: function (protocol, host, hostname, port, pathname, search, hash) { + this.protocol = protocol; + this.host = host; + this.hostname = hostname; + this.port = port || ''; + this.pathname = pathname || ''; + this.search = search || ''; + this.hash = hash || ''; + if (protocol) { + with (this) + this.href = protocol + '//' + host + pathname + search + hash; + } else if (host) { + with (this) + this.href = '//' + host + pathname + search + hash; + } else { + with (this) + this.href = pathname + search + hash; + } + }, + params: function (name) { + if (!this._params) { + var params = {}; + var pairs = this.search.substring(1).split(/[;&]/); + for (var i = 0, len = pairs.length; i < len; i++) { + if (!pairs[i]) + continue; + var pair = pairs[i].split(/=/); + var key = decodeURIComponent(pair[0].replace(/\+/g, '%20')); + var val = decodeURIComponent(pair[1].replace(/\+/g, '%20')); + if (!params[key]) + params[key] = []; + params[key].push(val); + } + this._params = params; + } + switch (typeof name) { + case 'undefined': + return this._params; + case 'object': + return this.build(name); + } + return this._params[name] ? this._params[name][0] : null; + }, + build: function (params) { + if (!params) + params = this._params; + var ret = new Location(); + var _search = this.search; + if (params) { + var search = []; + for (var key in params) + if (params.hasOwnProperty(key)) { + var val = params[key]; + switch (typeof val) { + case 'object': + for (var i = 0, len = val.length; i < len; i++) { + search.push(encodeURIComponent(key) + '=' + encodeURIComponent(val[i])); + } + break; + default: + search.push(encodeURIComponent(key) + '=' + encodeURIComponent(val)); + } + } + _search = '?' + search.join('&'); + } + with (this) + ret.init.apply(ret, [ + protocol, + host, + hostname, + port, + pathname, + _search, + hash + ]); + return ret; + } +}; +Location.regexp = new RegExp('^(?:(https?:)//(([^:/]+)(:[^/]+)?))?([^#?]*)(\\?[^#]*)?(#.*)?$'); +Location.parse = function (string) { + var matched = String(string).match(this.regexp); + var ret = new Location(); + ret.init.apply(ret, matched.slice(1)); + return ret; +}; +(function (root, factory) { + if (typeof module === 'object' && module.exports) { + module.exports = { Location: factory() }; + } else if (typeof define === 'function' && define.amd) { + define('micro-location@0.1.5#lib/micro-location', [], function () { + return { Location: factory() }; + }); + } else { + root.Location = factory(); + } +}(this, function () { + return Location; +})); +/*can-simple-dom@1.4.2#lib/extend*/ +define('can-simple-dom@1.4.2#lib/extend', function (require, exports, module) { + module.exports = function (a, b) { + for (var p in b) { + a[p] = b[p]; + } + return a; + }; +}); +/*can-simple-dom@1.4.2#lib/document/anchor-element*/ +define('can-simple-dom@1.4.2#lib/document/anchor-element', [ + 'require', + 'exports', + 'module', + './element', + 'micro-location', + '../extend' +], function (require, exports, module) { + var Element = require('./element'); + var microLocation = require('micro-location'); + var extend = require('../extend'); + const Location = microLocation.Location || microLocation; + function AnchorElement(tagName, ownerDocument) { + this.elementConstructor(tagName, ownerDocument); + extend(this, Location.parse('')); + } + AnchorElement.prototype = Object.create(Element.prototype); + AnchorElement.prototype.constructor = AnchorElement; + AnchorElement.prototype.elementConstructor = Element; + AnchorElement.prototype.setAttribute = function (_name, value) { + Element.prototype.setAttribute.apply(this, arguments); + if (_name.toLowerCase() === 'href') { + extend(this, Location.parse(value)); + } + }; + module.exports = AnchorElement; +}); +/*can-simple-dom@1.4.2#lib/document/utils*/ +define('can-simple-dom@1.4.2#lib/document/utils', function (require, exports, module) { + exports.propToAttr = function (Element, name) { + Object.defineProperty(Element.prototype, name, { + configurable: true, + enumerable: true, + get: function () { + return this.getAttribute(name); + }, + set: function (val) { + this.setAttribute(name, val); + } + }); + }; +}); +/*can-simple-dom@1.4.2#lib/document/input-element*/ +define('can-simple-dom@1.4.2#lib/document/input-element', [ + 'require', + 'exports', + 'module', + './element', + './utils' +], function (require, exports, module) { + var Element = require('./element'); + var propToAttr = require('./utils').propToAttr; + function InputElement(tagName, ownerDocument) { + this.elementConstructor(tagName, ownerDocument); + } + InputElement.prototype = Object.create(Element.prototype); + InputElement.prototype.constructor = InputElement; + InputElement.prototype.elementConstructor = Element; + propToAttr(InputElement, 'type'); + propToAttr(InputElement, 'value'); + Object.defineProperty(InputElement.prototype, 'checked', { + configurable: true, + enumerable: true, + get: function () { + return this.hasAttribute('checked'); + }, + set: function (value) { + if (value) { + this.setAttribute('checked', ''); + } else { + this.removeAttribute('checked'); + } + } + }); + module.exports = InputElement; +}); +/*can-simple-dom@1.4.2#lib/document/option-element*/ +define('can-simple-dom@1.4.2#lib/document/option-element', [ + 'require', + 'exports', + 'module', + './element', + './utils' +], function (require, exports, module) { + var Element = require('./element'); + var propToAttr = require('./utils').propToAttr; + function OptionElement(tagName, ownerDocument) { + this.elementConstructor(tagName, ownerDocument); + } + OptionElement.prototype = Object.create(Element.prototype); + OptionElement.prototype.constructor = OptionElement; + OptionElement.prototype.elementConstructor = Element; + propToAttr(OptionElement, 'value'); + Object.defineProperty(OptionElement.prototype, 'selected', { + enumerable: true, + configurable: true, + get: function () { + var val = this.value || ''; + var parent = this.parentNode; + return parent && parent.value == val; + }, + set: function (val) { + if (val) { + var parent = this.parentNode; + if (parent) { + parent.value = this.value; + } + } + } + }); + module.exports = OptionElement; +}); +/*can-simple-dom@1.4.2#lib/document/select-element*/ +define('can-simple-dom@1.4.2#lib/document/select-element', [ + 'require', + 'exports', + 'module', + './element', + './utils' +], function (require, exports, module) { + var Element = require('./element'); + var propToAttr = require('./utils').propToAttr; + function SelectElement(tagName, ownerDocument) { + this.elementConstructor(tagName, ownerDocument); + this.selectedIndex = 0; + } + SelectElement.prototype = Object.create(Element.prototype); + SelectElement.prototype.constructor = SelectElement; + SelectElement.prototype.elementConstructor = Element; + propToAttr(SelectElement, 'value'); + module.exports = SelectElement; +}); +/*can-simple-dom@1.4.2#lib/document*/ +define('can-simple-dom@1.4.2#lib/document', [ + 'require', + 'exports', + 'module', + './document/node', + './document/element', + './document/text', + './document/comment', + './document/document-fragment', + './document/anchor-element', + './document/input-element', + './document/option-element', + './document/select-element' +], function (require, exports, module) { + var Node = require('./document/node').Node; + var Element = require('./document/element'); + var Text = require('./document/text'); + var Comment = require('./document/comment'); + var DocumentFragment = require('./document/document-fragment'); + var AnchorElement = require('./document/anchor-element'); + var InputElement = require('./document/input-element'); + var OptionElement = require('./document/option-element'); + var SelectElement = require('./document/select-element'); + var noop = Function.prototype; + function Document() { + this.nodeConstructor(9, '#document', null, this); + var documentElement = new Element('html', this); + var body = new Element('body', this); + var head = new Element('head', this); + documentElement.appendChild(head); + documentElement.appendChild(body); + this.appendChild(documentElement); + var self = this; + this.implementation = { + createHTMLDocument: function (content) { + var document = new Document(); + var frag = self.__parser.parse(content); + var body = Element.prototype.getElementsByTagName.call(frag, 'body')[0]; + var head = Element.prototype.getElementsByTagName.call(frag, 'head')[0]; + if (!body && !head) { + document.body.appendChild(frag); + } else { + if (body) { + document.documentElement.replaceChild(body, document.body); + } + if (head) { + document.documentElement.replaceChild(head, document.head); + } + document.documentElement.appendChild(frag); + } + document.__addSerializerAndParser(self.__serializer, self.__parser); + return document; + } + }; + } + Document.prototype = Object.create(Node.prototype); + Document.prototype.constructor = Document; + Document.prototype.nodeConstructor = Node; + const specialElements = { + 'a': AnchorElement, + 'input': InputElement, + 'option': OptionElement, + 'select': SelectElement + }; + Document.prototype.createElement = function (tagName) { + var Special = specialElements[tagName.toLowerCase()]; + if (Special) { + return new Special(tagName, this); + } + return new Element(tagName, this); + }; + Document.prototype.createTextNode = function (text) { + return new Text(text, this); + }; + Document.prototype.createComment = function (text) { + return new Comment(text, this); + }; + Document.prototype.createDocumentFragment = function () { + return new DocumentFragment(this); + }; + Document.prototype.getElementsByTagName = function (name) { + name = name.toUpperCase(); + var elements = []; + var cur = this.firstChild; + while (cur) { + if (cur.nodeType === Node.ELEMENT_NODE) { + if (cur.nodeName === name || name === '*') { + elements.push(cur); + } + elements.push.apply(elements, cur.getElementsByTagName(name)); + } + cur = cur.nextSibling; + } + return elements; + }; + Document.prototype.getElementById = function (id) { + return Element.prototype.getElementById.apply(this.documentElement, arguments); + }; + Document.prototype.__addSerializerAndParser = function (serializer, parser) { + this.__parser = parser; + this.__serializer = serializer; + }; + if (Object.defineProperty) { + Object.defineProperty(Document.prototype, 'currentScript', { + get: function () { + var scripts = this.getElementsByTagName('script'); + var first = scripts[scripts.length - 1]; + if (!first) { + first = this.createElement('script'); + } + return first; + } + }); + Object.defineProperty(Document.prototype, 'documentElement', { + get: function () { + return this.firstChild; + }, + set: noop + }); + function firstOfKind(root, nodeName) { + if (root == null) + return null; + var node = root.firstChild; + while (node) { + if (node.nodeName === nodeName) { + return node; + } + node = node.nextSibling; + } + return null; + } + [ + 'head', + 'body' + ].forEach(function (localName) { + var nodeName = localName.toUpperCase(); + Object.defineProperty(Document.prototype, localName, { + get: function () { + return firstOfKind(this.documentElement, nodeName); + }, + set: noop + }); + }); + } + module.exports = Document; +}); +/*can-simple-dom@1.4.2#lib/event*/ +define('can-simple-dom@1.4.2#lib/event', [ + 'require', + 'exports', + 'module', + './document/node', + './document' +], function (require, exports, module) { + var Node = require('./document/node').Node; + var Document = require('./document'); + var Event = function () { + }; + Event.prototype.initEvent = function (type, bubbles, cancelable) { + this.type = type; + this.bubbles = !!bubbles; + this.cancelable = !!cancelable; + }; + Event.prototype.stopPropagation = function () { + this.isPropagationStopped = true; + }; + Event.prototype.preventDefault = function () { + this.isDefaultPrevented = true; + }; + Document.prototype.createEvent = function (type) { + return new Event(); + }; + Node.prototype.addEventListener = function (event, handler, capture) { + if (!this.__handlers) { + Object.defineProperty(this, '__handlers', { + value: {}, + enumerable: false + }); + } + var phase = capture ? 'capture' : 'bubble'; + var handlersByType = this.__handlers[event + ' ' + phase]; + if (!handlersByType) { + handlersByType = this.__handlers[event + ' ' + phase] = []; + } + if (handlersByType.indexOf(handler) === -1) { + handlersByType.push(handler); + } + }; + Node.prototype.removeEventListener = function (event, handler, capture) { + if (this.__handlers) { + var phase = capture ? 'capture' : 'bubble'; + var handlersByType = this.__handlers[event + ' ' + phase]; + if (handlersByType) { + var index = 0; + while (index < handlersByType.length) { + if (handlersByType[index] === handler) { + handlersByType.splice(index, 1); + } else { + index++; + } + } + } + } + }; + Node.prototype.dispatchEvent = function (event) { + event.target = this; + var cur = this; + var dispatchHandlers = []; + do { + var handlers = cur.__handlers && cur.__handlers[event.type + ' bubble']; + if (handlers) { + dispatchHandlers.push({ + node: cur, + handlers: handlers + }); + } + cur = cur.parentNode; + } while (event.bubbles && cur); + for (var i = 0; i < dispatchHandlers.length; i++) { + var dispatches = dispatchHandlers[i]; + event.currentTarget = dispatches.node; + for (var h = 0; h < dispatches.handlers.length; h++) { + var handler = dispatches.handlers[h]; + var res = handler.call(this, event); + if (res) { + event.stopPropagation(); + event.preventDefault(); + } + if (event.isImmediatePropagationStopped) { + return !event.isDefaultPrevented; + } + } + if (event.isPropagationStopped) { + return !event.isDefaultPrevented; + } + } + return !event.isDefaultPrevented; + }; + module.exports = Event; +}); +/*he@1.2.0#he*/ +; +(function (root) { + var freeExports = typeof exports == 'object' && exports; + var freeModule = typeof module == 'object' && module && module.exports == freeExports && module; + var freeGlobal = typeof global == 'object' && global; + if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) { + root = freeGlobal; + } + var regexAstralSymbols = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g; + var regexAsciiWhitelist = /[\x01-\x7F]/g; + var regexBmpWhitelist = /[\x01-\t\x0B\f\x0E-\x1F\x7F\x81\x8D\x8F\x90\x9D\xA0-\uFFFF]/g; + var regexEncodeNonAscii = /<\u20D2|=\u20E5|>\u20D2|\u205F\u200A|\u219D\u0338|\u2202\u0338|\u2220\u20D2|\u2229\uFE00|\u222A\uFE00|\u223C\u20D2|\u223D\u0331|\u223E\u0333|\u2242\u0338|\u224B\u0338|\u224D\u20D2|\u224E\u0338|\u224F\u0338|\u2250\u0338|\u2261\u20E5|\u2264\u20D2|\u2265\u20D2|\u2266\u0338|\u2267\u0338|\u2268\uFE00|\u2269\uFE00|\u226A\u0338|\u226A\u20D2|\u226B\u0338|\u226B\u20D2|\u227F\u0338|\u2282\u20D2|\u2283\u20D2|\u228A\uFE00|\u228B\uFE00|\u228F\u0338|\u2290\u0338|\u2293\uFE00|\u2294\uFE00|\u22B4\u20D2|\u22B5\u20D2|\u22D8\u0338|\u22D9\u0338|\u22DA\uFE00|\u22DB\uFE00|\u22F5\u0338|\u22F9\u0338|\u2933\u0338|\u29CF\u0338|\u29D0\u0338|\u2A6D\u0338|\u2A70\u0338|\u2A7D\u0338|\u2A7E\u0338|\u2AA1\u0338|\u2AA2\u0338|\u2AAC\uFE00|\u2AAD\uFE00|\u2AAF\u0338|\u2AB0\u0338|\u2AC5\u0338|\u2AC6\u0338|\u2ACB\uFE00|\u2ACC\uFE00|\u2AFD\u20E5|[\xA0-\u0113\u0116-\u0122\u0124-\u012B\u012E-\u014D\u0150-\u017E\u0192\u01B5\u01F5\u0237\u02C6\u02C7\u02D8-\u02DD\u0311\u0391-\u03A1\u03A3-\u03A9\u03B1-\u03C9\u03D1\u03D2\u03D5\u03D6\u03DC\u03DD\u03F0\u03F1\u03F5\u03F6\u0401-\u040C\u040E-\u044F\u0451-\u045C\u045E\u045F\u2002-\u2005\u2007-\u2010\u2013-\u2016\u2018-\u201A\u201C-\u201E\u2020-\u2022\u2025\u2026\u2030-\u2035\u2039\u203A\u203E\u2041\u2043\u2044\u204F\u2057\u205F-\u2063\u20AC\u20DB\u20DC\u2102\u2105\u210A-\u2113\u2115-\u211E\u2122\u2124\u2127-\u2129\u212C\u212D\u212F-\u2131\u2133-\u2138\u2145-\u2148\u2153-\u215E\u2190-\u219B\u219D-\u21A7\u21A9-\u21AE\u21B0-\u21B3\u21B5-\u21B7\u21BA-\u21DB\u21DD\u21E4\u21E5\u21F5\u21FD-\u2205\u2207-\u2209\u220B\u220C\u220F-\u2214\u2216-\u2218\u221A\u221D-\u2238\u223A-\u2257\u2259\u225A\u225C\u225F-\u2262\u2264-\u228B\u228D-\u229B\u229D-\u22A5\u22A7-\u22B0\u22B2-\u22BB\u22BD-\u22DB\u22DE-\u22E3\u22E6-\u22F7\u22F9-\u22FE\u2305\u2306\u2308-\u2310\u2312\u2313\u2315\u2316\u231C-\u231F\u2322\u2323\u232D\u232E\u2336\u233D\u233F\u237C\u23B0\u23B1\u23B4-\u23B6\u23DC-\u23DF\u23E2\u23E7\u2423\u24C8\u2500\u2502\u250C\u2510\u2514\u2518\u251C\u2524\u252C\u2534\u253C\u2550-\u256C\u2580\u2584\u2588\u2591-\u2593\u25A1\u25AA\u25AB\u25AD\u25AE\u25B1\u25B3-\u25B5\u25B8\u25B9\u25BD-\u25BF\u25C2\u25C3\u25CA\u25CB\u25EC\u25EF\u25F8-\u25FC\u2605\u2606\u260E\u2640\u2642\u2660\u2663\u2665\u2666\u266A\u266D-\u266F\u2713\u2717\u2720\u2736\u2758\u2772\u2773\u27C8\u27C9\u27E6-\u27ED\u27F5-\u27FA\u27FC\u27FF\u2902-\u2905\u290C-\u2913\u2916\u2919-\u2920\u2923-\u292A\u2933\u2935-\u2939\u293C\u293D\u2945\u2948-\u294B\u294E-\u2976\u2978\u2979\u297B-\u297F\u2985\u2986\u298B-\u2996\u299A\u299C\u299D\u29A4-\u29B7\u29B9\u29BB\u29BC\u29BE-\u29C5\u29C9\u29CD-\u29D0\u29DC-\u29DE\u29E3-\u29E5\u29EB\u29F4\u29F6\u2A00-\u2A02\u2A04\u2A06\u2A0C\u2A0D\u2A10-\u2A17\u2A22-\u2A27\u2A29\u2A2A\u2A2D-\u2A31\u2A33-\u2A3C\u2A3F\u2A40\u2A42-\u2A4D\u2A50\u2A53-\u2A58\u2A5A-\u2A5D\u2A5F\u2A66\u2A6A\u2A6D-\u2A75\u2A77-\u2A9A\u2A9D-\u2AA2\u2AA4-\u2AB0\u2AB3-\u2AC8\u2ACB\u2ACC\u2ACF-\u2ADB\u2AE4\u2AE6-\u2AE9\u2AEB-\u2AF3\u2AFD\uFB00-\uFB04]|\uD835[\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDCCF\uDD04\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDD6B]/g; + var encodeMap = { + '\xAD': 'shy', + '‌': 'zwnj', + '‍': 'zwj', + '\u200E': 'lrm', + '\u2063': 'ic', + '\u2062': 'it', + '\u2061': 'af', + '\u200F': 'rlm', + '\u200B': 'ZeroWidthSpace', + '\u2060': 'NoBreak', + '̑': 'DownBreve', + '⃛': 'tdot', + '⃜': 'DotDot', + '\t': 'Tab', + '\n': 'NewLine', + '\u2008': 'puncsp', + '\u205F': 'MediumSpace', + '\u2009': 'thinsp', + '\u200A': 'hairsp', + '\u2004': 'emsp13', + '\u2002': 'ensp', + '\u2005': 'emsp14', + '\u2003': 'emsp', + '\u2007': 'numsp', + '\xA0': 'nbsp', + '\u205F\u200A': 'ThickSpace', + '\u203E': 'oline', + '_': 'lowbar', + '\u2010': 'dash', + '\u2013': 'ndash', + '\u2014': 'mdash', + '\u2015': 'horbar', + ',': 'comma', + ';': 'semi', + '\u204F': 'bsemi', + ':': 'colon', + '\u2A74': 'Colone', + '!': 'excl', + '\xA1': 'iexcl', + '?': 'quest', + '\xBF': 'iquest', + '.': 'period', + '\u2025': 'nldr', + '\u2026': 'mldr', + '\xB7': 'middot', + '\'': 'apos', + '\u2018': 'lsquo', + '\u2019': 'rsquo', + '\u201A': 'sbquo', + '\u2039': 'lsaquo', + '\u203A': 'rsaquo', + '"': 'quot', + '\u201C': 'ldquo', + '\u201D': 'rdquo', + '\u201E': 'bdquo', + '\xAB': 'laquo', + '\xBB': 'raquo', + '(': 'lpar', + ')': 'rpar', + '[': 'lsqb', + ']': 'rsqb', + '{': 'lcub', + '}': 'rcub', + '\u2308': 'lceil', + '\u2309': 'rceil', + '\u230A': 'lfloor', + '\u230B': 'rfloor', + '\u2985': 'lopar', + '\u2986': 'ropar', + '\u298B': 'lbrke', + '\u298C': 'rbrke', + '\u298D': 'lbrkslu', + '\u298E': 'rbrksld', + '\u298F': 'lbrksld', + '\u2990': 'rbrkslu', + '\u2991': 'langd', + '\u2992': 'rangd', + '\u2993': 'lparlt', + '\u2994': 'rpargt', + '\u2995': 'gtlPar', + '\u2996': 'ltrPar', + '\u27E6': 'lobrk', + '\u27E7': 'robrk', + '\u27E8': 'lang', + '\u27E9': 'rang', + '\u27EA': 'Lang', + '\u27EB': 'Rang', + '\u27EC': 'loang', + '\u27ED': 'roang', + '\u2772': 'lbbrk', + '\u2773': 'rbbrk', + '\u2016': 'Vert', + '\xA7': 'sect', + '\xB6': 'para', + '@': 'commat', + '*': 'ast', + '/': 'sol', + 'undefined': null, + '&': 'amp', + '#': 'num', + '%': 'percnt', + '\u2030': 'permil', + '\u2031': 'pertenk', + '\u2020': 'dagger', + '\u2021': 'Dagger', + '\u2022': 'bull', + '\u2043': 'hybull', + '\u2032': 'prime', + '\u2033': 'Prime', + '\u2034': 'tprime', + '\u2057': 'qprime', + '\u2035': 'bprime', + '\u2041': 'caret', + '`': 'grave', + '\xB4': 'acute', + '\u02DC': 'tilde', + '^': 'Hat', + '\xAF': 'macr', + '\u02D8': 'breve', + '\u02D9': 'dot', + '\xA8': 'die', + '\u02DA': 'ring', + '\u02DD': 'dblac', + '\xB8': 'cedil', + '\u02DB': 'ogon', + 'ˆ': 'circ', + 'ˇ': 'caron', + '\xB0': 'deg', + '\xA9': 'copy', + '\xAE': 'reg', + '\u2117': 'copysr', + '\u2118': 'wp', + '\u211E': 'rx', + '\u2127': 'mho', + '\u2129': 'iiota', + '\u2190': 'larr', + '\u219A': 'nlarr', + '\u2192': 'rarr', + '\u219B': 'nrarr', + '\u2191': 'uarr', + '\u2193': 'darr', + '\u2194': 'harr', + '\u21AE': 'nharr', + '\u2195': 'varr', + '\u2196': 'nwarr', + '\u2197': 'nearr', + '\u2198': 'searr', + '\u2199': 'swarr', + '\u219D': 'rarrw', + '\u219D̸': 'nrarrw', + '\u219E': 'Larr', + '\u219F': 'Uarr', + '\u21A0': 'Rarr', + '\u21A1': 'Darr', + '\u21A2': 'larrtl', + '\u21A3': 'rarrtl', + '\u21A4': 'mapstoleft', + '\u21A5': 'mapstoup', + '\u21A6': 'map', + '\u21A7': 'mapstodown', + '\u21A9': 'larrhk', + '\u21AA': 'rarrhk', + '\u21AB': 'larrlp', + '\u21AC': 'rarrlp', + '\u21AD': 'harrw', + '\u21B0': 'lsh', + '\u21B1': 'rsh', + '\u21B2': 'ldsh', + '\u21B3': 'rdsh', + '\u21B5': 'crarr', + '\u21B6': 'cularr', + '\u21B7': 'curarr', + '\u21BA': 'olarr', + '\u21BB': 'orarr', + '\u21BC': 'lharu', + '\u21BD': 'lhard', + '\u21BE': 'uharr', + '\u21BF': 'uharl', + '\u21C0': 'rharu', + '\u21C1': 'rhard', + '\u21C2': 'dharr', + '\u21C3': 'dharl', + '\u21C4': 'rlarr', + '\u21C5': 'udarr', + '\u21C6': 'lrarr', + '\u21C7': 'llarr', + '\u21C8': 'uuarr', + '\u21C9': 'rrarr', + '\u21CA': 'ddarr', + '\u21CB': 'lrhar', + '\u21CC': 'rlhar', + '\u21D0': 'lArr', + '\u21CD': 'nlArr', + '\u21D1': 'uArr', + '\u21D2': 'rArr', + '\u21CF': 'nrArr', + '\u21D3': 'dArr', + '\u21D4': 'iff', + '\u21CE': 'nhArr', + '\u21D5': 'vArr', + '\u21D6': 'nwArr', + '\u21D7': 'neArr', + '\u21D8': 'seArr', + '\u21D9': 'swArr', + '\u21DA': 'lAarr', + '\u21DB': 'rAarr', + '\u21DD': 'zigrarr', + '\u21E4': 'larrb', + '\u21E5': 'rarrb', + '\u21F5': 'duarr', + '\u21FD': 'loarr', + '\u21FE': 'roarr', + '\u21FF': 'hoarr', + '\u2200': 'forall', + '\u2201': 'comp', + '\u2202': 'part', + '\u2202̸': 'npart', + '\u2203': 'exist', + '\u2204': 'nexist', + '\u2205': 'empty', + '\u2207': 'Del', + '\u2208': 'in', + '\u2209': 'notin', + '\u220B': 'ni', + '\u220C': 'notni', + '\u03F6': 'bepsi', + '\u220F': 'prod', + '\u2210': 'coprod', + '\u2211': 'sum', + '+': 'plus', + '\xB1': 'pm', + '\xF7': 'div', + '\xD7': 'times', + '<': 'lt', + '\u226E': 'nlt', + '<⃒': 'nvlt', + '=': 'equals', + '\u2260': 'ne', + '=⃥': 'bne', + '\u2A75': 'Equal', + '>': 'gt', + '\u226F': 'ngt', + '>⃒': 'nvgt', + '\xAC': 'not', + '|': 'vert', + '\xA6': 'brvbar', + '\u2212': 'minus', + '\u2213': 'mp', + '\u2214': 'plusdo', + '\u2044': 'frasl', + '\u2216': 'setmn', + '\u2217': 'lowast', + '\u2218': 'compfn', + '\u221A': 'Sqrt', + '\u221D': 'prop', + '\u221E': 'infin', + '\u221F': 'angrt', + '\u2220': 'ang', + '\u2220⃒': 'nang', + '\u2221': 'angmsd', + '\u2222': 'angsph', + '\u2223': 'mid', + '\u2224': 'nmid', + '\u2225': 'par', + '\u2226': 'npar', + '\u2227': 'and', + '\u2228': 'or', + '\u2229': 'cap', + '\u2229︀': 'caps', + '\u222A': 'cup', + '\u222A︀': 'cups', + '\u222B': 'int', + '\u222C': 'Int', + '\u222D': 'tint', + '\u2A0C': 'qint', + '\u222E': 'oint', + '\u222F': 'Conint', + '\u2230': 'Cconint', + '\u2231': 'cwint', + '\u2232': 'cwconint', + '\u2233': 'awconint', + '\u2234': 'there4', + '\u2235': 'becaus', + '\u2236': 'ratio', + '\u2237': 'Colon', + '\u2238': 'minusd', + '\u223A': 'mDDot', + '\u223B': 'homtht', + '\u223C': 'sim', + '\u2241': 'nsim', + '\u223C⃒': 'nvsim', + '\u223D': 'bsim', + '\u223Ḏ': 'race', + '\u223E': 'ac', + '\u223E̳': 'acE', + '\u223F': 'acd', + '\u2240': 'wr', + '\u2242': 'esim', + '\u2242̸': 'nesim', + '\u2243': 'sime', + '\u2244': 'nsime', + '\u2245': 'cong', + '\u2247': 'ncong', + '\u2246': 'simne', + '\u2248': 'ap', + '\u2249': 'nap', + '\u224A': 'ape', + '\u224B': 'apid', + '\u224B̸': 'napid', + '\u224C': 'bcong', + '\u224D': 'CupCap', + '\u226D': 'NotCupCap', + '\u224D⃒': 'nvap', + '\u224E': 'bump', + '\u224E̸': 'nbump', + '\u224F': 'bumpe', + '\u224F̸': 'nbumpe', + '\u2250': 'doteq', + '\u2250̸': 'nedot', + '\u2251': 'eDot', + '\u2252': 'efDot', + '\u2253': 'erDot', + '\u2254': 'colone', + '\u2255': 'ecolon', + '\u2256': 'ecir', + '\u2257': 'cire', + '\u2259': 'wedgeq', + '\u225A': 'veeeq', + '\u225C': 'trie', + '\u225F': 'equest', + '\u2261': 'equiv', + '\u2262': 'nequiv', + '\u2261⃥': 'bnequiv', + '\u2264': 'le', + '\u2270': 'nle', + '\u2264⃒': 'nvle', + '\u2265': 'ge', + '\u2271': 'nge', + '\u2265⃒': 'nvge', + '\u2266': 'lE', + '\u2266̸': 'nlE', + '\u2267': 'gE', + '\u2267̸': 'ngE', + '\u2268︀': 'lvnE', + '\u2268': 'lnE', + '\u2269': 'gnE', + '\u2269︀': 'gvnE', + '\u226A': 'll', + '\u226A̸': 'nLtv', + '\u226A⃒': 'nLt', + '\u226B': 'gg', + '\u226B̸': 'nGtv', + '\u226B⃒': 'nGt', + '\u226C': 'twixt', + '\u2272': 'lsim', + '\u2274': 'nlsim', + '\u2273': 'gsim', + '\u2275': 'ngsim', + '\u2276': 'lg', + '\u2278': 'ntlg', + '\u2277': 'gl', + '\u2279': 'ntgl', + '\u227A': 'pr', + '\u2280': 'npr', + '\u227B': 'sc', + '\u2281': 'nsc', + '\u227C': 'prcue', + '\u22E0': 'nprcue', + '\u227D': 'sccue', + '\u22E1': 'nsccue', + '\u227E': 'prsim', + '\u227F': 'scsim', + '\u227F̸': 'NotSucceedsTilde', + '\u2282': 'sub', + '\u2284': 'nsub', + '\u2282⃒': 'vnsub', + '\u2283': 'sup', + '\u2285': 'nsup', + '\u2283⃒': 'vnsup', + '\u2286': 'sube', + '\u2288': 'nsube', + '\u2287': 'supe', + '\u2289': 'nsupe', + '\u228A︀': 'vsubne', + '\u228A': 'subne', + '\u228B︀': 'vsupne', + '\u228B': 'supne', + '\u228D': 'cupdot', + '\u228E': 'uplus', + '\u228F': 'sqsub', + '\u228F̸': 'NotSquareSubset', + '\u2290': 'sqsup', + '\u2290̸': 'NotSquareSuperset', + '\u2291': 'sqsube', + '\u22E2': 'nsqsube', + '\u2292': 'sqsupe', + '\u22E3': 'nsqsupe', + '\u2293': 'sqcap', + '\u2293︀': 'sqcaps', + '\u2294': 'sqcup', + '\u2294︀': 'sqcups', + '\u2295': 'oplus', + '\u2296': 'ominus', + '\u2297': 'otimes', + '\u2298': 'osol', + '\u2299': 'odot', + '\u229A': 'ocir', + '\u229B': 'oast', + '\u229D': 'odash', + '\u229E': 'plusb', + '\u229F': 'minusb', + '\u22A0': 'timesb', + '\u22A1': 'sdotb', + '\u22A2': 'vdash', + '\u22AC': 'nvdash', + '\u22A3': 'dashv', + '\u22A4': 'top', + '\u22A5': 'bot', + '\u22A7': 'models', + '\u22A8': 'vDash', + '\u22AD': 'nvDash', + '\u22A9': 'Vdash', + '\u22AE': 'nVdash', + '\u22AA': 'Vvdash', + '\u22AB': 'VDash', + '\u22AF': 'nVDash', + '\u22B0': 'prurel', + '\u22B2': 'vltri', + '\u22EA': 'nltri', + '\u22B3': 'vrtri', + '\u22EB': 'nrtri', + '\u22B4': 'ltrie', + '\u22EC': 'nltrie', + '\u22B4⃒': 'nvltrie', + '\u22B5': 'rtrie', + '\u22ED': 'nrtrie', + '\u22B5⃒': 'nvrtrie', + '\u22B6': 'origof', + '\u22B7': 'imof', + '\u22B8': 'mumap', + '\u22B9': 'hercon', + '\u22BA': 'intcal', + '\u22BB': 'veebar', + '\u22BD': 'barvee', + '\u22BE': 'angrtvb', + '\u22BF': 'lrtri', + '\u22C0': 'Wedge', + '\u22C1': 'Vee', + '\u22C2': 'xcap', + '\u22C3': 'xcup', + '\u22C4': 'diam', + '\u22C5': 'sdot', + '\u22C6': 'Star', + '\u22C7': 'divonx', + '\u22C8': 'bowtie', + '\u22C9': 'ltimes', + '\u22CA': 'rtimes', + '\u22CB': 'lthree', + '\u22CC': 'rthree', + '\u22CD': 'bsime', + '\u22CE': 'cuvee', + '\u22CF': 'cuwed', + '\u22D0': 'Sub', + '\u22D1': 'Sup', + '\u22D2': 'Cap', + '\u22D3': 'Cup', + '\u22D4': 'fork', + '\u22D5': 'epar', + '\u22D6': 'ltdot', + '\u22D7': 'gtdot', + '\u22D8': 'Ll', + '\u22D8̸': 'nLl', + '\u22D9': 'Gg', + '\u22D9̸': 'nGg', + '\u22DA︀': 'lesg', + '\u22DA': 'leg', + '\u22DB': 'gel', + '\u22DB︀': 'gesl', + '\u22DE': 'cuepr', + '\u22DF': 'cuesc', + '\u22E6': 'lnsim', + '\u22E7': 'gnsim', + '\u22E8': 'prnsim', + '\u22E9': 'scnsim', + '\u22EE': 'vellip', + '\u22EF': 'ctdot', + '\u22F0': 'utdot', + '\u22F1': 'dtdot', + '\u22F2': 'disin', + '\u22F3': 'isinsv', + '\u22F4': 'isins', + '\u22F5': 'isindot', + '\u22F5̸': 'notindot', + '\u22F6': 'notinvc', + '\u22F7': 'notinvb', + '\u22F9': 'isinE', + '\u22F9̸': 'notinE', + '\u22FA': 'nisd', + '\u22FB': 'xnis', + '\u22FC': 'nis', + '\u22FD': 'notnivc', + '\u22FE': 'notnivb', + '\u2305': 'barwed', + '\u2306': 'Barwed', + '\u230C': 'drcrop', + '\u230D': 'dlcrop', + '\u230E': 'urcrop', + '\u230F': 'ulcrop', + '\u2310': 'bnot', + '\u2312': 'profline', + '\u2313': 'profsurf', + '\u2315': 'telrec', + '\u2316': 'target', + '\u231C': 'ulcorn', + '\u231D': 'urcorn', + '\u231E': 'dlcorn', + '\u231F': 'drcorn', + '\u2322': 'frown', + '\u2323': 'smile', + '\u232D': 'cylcty', + '\u232E': 'profalar', + '\u2336': 'topbot', + '\u233D': 'ovbar', + '\u233F': 'solbar', + '\u237C': 'angzarr', + '\u23B0': 'lmoust', + '\u23B1': 'rmoust', + '\u23B4': 'tbrk', + '\u23B5': 'bbrk', + '\u23B6': 'bbrktbrk', + '\u23DC': 'OverParenthesis', + '\u23DD': 'UnderParenthesis', + '\u23DE': 'OverBrace', + '\u23DF': 'UnderBrace', + '\u23E2': 'trpezium', + '\u23E7': 'elinters', + '\u2423': 'blank', + '\u2500': 'boxh', + '\u2502': 'boxv', + '\u250C': 'boxdr', + '\u2510': 'boxdl', + '\u2514': 'boxur', + '\u2518': 'boxul', + '\u251C': 'boxvr', + '\u2524': 'boxvl', + '\u252C': 'boxhd', + '\u2534': 'boxhu', + '\u253C': 'boxvh', + '\u2550': 'boxH', + '\u2551': 'boxV', + '\u2552': 'boxdR', + '\u2553': 'boxDr', + '\u2554': 'boxDR', + '\u2555': 'boxdL', + '\u2556': 'boxDl', + '\u2557': 'boxDL', + '\u2558': 'boxuR', + '\u2559': 'boxUr', + '\u255A': 'boxUR', + '\u255B': 'boxuL', + '\u255C': 'boxUl', + '\u255D': 'boxUL', + '\u255E': 'boxvR', + '\u255F': 'boxVr', + '\u2560': 'boxVR', + '\u2561': 'boxvL', + '\u2562': 'boxVl', + '\u2563': 'boxVL', + '\u2564': 'boxHd', + '\u2565': 'boxhD', + '\u2566': 'boxHD', + '\u2567': 'boxHu', + '\u2568': 'boxhU', + '\u2569': 'boxHU', + '\u256A': 'boxvH', + '\u256B': 'boxVh', + '\u256C': 'boxVH', + '\u2580': 'uhblk', + '\u2584': 'lhblk', + '\u2588': 'block', + '\u2591': 'blk14', + '\u2592': 'blk12', + '\u2593': 'blk34', + '\u25A1': 'squ', + '\u25AA': 'squf', + '\u25AB': 'EmptyVerySmallSquare', + '\u25AD': 'rect', + '\u25AE': 'marker', + '\u25B1': 'fltns', + '\u25B3': 'xutri', + '\u25B4': 'utrif', + '\u25B5': 'utri', + '\u25B8': 'rtrif', + '\u25B9': 'rtri', + '\u25BD': 'xdtri', + '\u25BE': 'dtrif', + '\u25BF': 'dtri', + '\u25C2': 'ltrif', + '\u25C3': 'ltri', + '\u25CA': 'loz', + '\u25CB': 'cir', + '\u25EC': 'tridot', + '\u25EF': 'xcirc', + '\u25F8': 'ultri', + '\u25F9': 'urtri', + '\u25FA': 'lltri', + '\u25FB': 'EmptySmallSquare', + '\u25FC': 'FilledSmallSquare', + '\u2605': 'starf', + '\u2606': 'star', + '\u260E': 'phone', + '\u2640': 'female', + '\u2642': 'male', + '\u2660': 'spades', + '\u2663': 'clubs', + '\u2665': 'hearts', + '\u2666': 'diams', + '\u266A': 'sung', + '\u2713': 'check', + '\u2717': 'cross', + '\u2720': 'malt', + '\u2736': 'sext', + '\u2758': 'VerticalSeparator', + '\u27C8': 'bsolhsub', + '\u27C9': 'suphsol', + '\u27F5': 'xlarr', + '\u27F6': 'xrarr', + '\u27F7': 'xharr', + '\u27F8': 'xlArr', + '\u27F9': 'xrArr', + '\u27FA': 'xhArr', + '\u27FC': 'xmap', + '\u27FF': 'dzigrarr', + '\u2902': 'nvlArr', + '\u2903': 'nvrArr', + '\u2904': 'nvHarr', + '\u2905': 'Map', + '\u290C': 'lbarr', + '\u290D': 'rbarr', + '\u290E': 'lBarr', + '\u290F': 'rBarr', + '\u2910': 'RBarr', + '\u2911': 'DDotrahd', + '\u2912': 'UpArrowBar', + '\u2913': 'DownArrowBar', + '\u2916': 'Rarrtl', + '\u2919': 'latail', + '\u291A': 'ratail', + '\u291B': 'lAtail', + '\u291C': 'rAtail', + '\u291D': 'larrfs', + '\u291E': 'rarrfs', + '\u291F': 'larrbfs', + '\u2920': 'rarrbfs', + '\u2923': 'nwarhk', + '\u2924': 'nearhk', + '\u2925': 'searhk', + '\u2926': 'swarhk', + '\u2927': 'nwnear', + '\u2928': 'toea', + '\u2929': 'tosa', + '\u292A': 'swnwar', + '\u2933': 'rarrc', + '\u2933̸': 'nrarrc', + '\u2935': 'cudarrr', + '\u2936': 'ldca', + '\u2937': 'rdca', + '\u2938': 'cudarrl', + '\u2939': 'larrpl', + '\u293C': 'curarrm', + '\u293D': 'cularrp', + '\u2945': 'rarrpl', + '\u2948': 'harrcir', + '\u2949': 'Uarrocir', + '\u294A': 'lurdshar', + '\u294B': 'ldrushar', + '\u294E': 'LeftRightVector', + '\u294F': 'RightUpDownVector', + '\u2950': 'DownLeftRightVector', + '\u2951': 'LeftUpDownVector', + '\u2952': 'LeftVectorBar', + '\u2953': 'RightVectorBar', + '\u2954': 'RightUpVectorBar', + '\u2955': 'RightDownVectorBar', + '\u2956': 'DownLeftVectorBar', + '\u2957': 'DownRightVectorBar', + '\u2958': 'LeftUpVectorBar', + '\u2959': 'LeftDownVectorBar', + '\u295A': 'LeftTeeVector', + '\u295B': 'RightTeeVector', + '\u295C': 'RightUpTeeVector', + '\u295D': 'RightDownTeeVector', + '\u295E': 'DownLeftTeeVector', + '\u295F': 'DownRightTeeVector', + '\u2960': 'LeftUpTeeVector', + '\u2961': 'LeftDownTeeVector', + '\u2962': 'lHar', + '\u2963': 'uHar', + '\u2964': 'rHar', + '\u2965': 'dHar', + '\u2966': 'luruhar', + '\u2967': 'ldrdhar', + '\u2968': 'ruluhar', + '\u2969': 'rdldhar', + '\u296A': 'lharul', + '\u296B': 'llhard', + '\u296C': 'rharul', + '\u296D': 'lrhard', + '\u296E': 'udhar', + '\u296F': 'duhar', + '\u2970': 'RoundImplies', + '\u2971': 'erarr', + '\u2972': 'simrarr', + '\u2973': 'larrsim', + '\u2974': 'rarrsim', + '\u2975': 'rarrap', + '\u2976': 'ltlarr', + '\u2978': 'gtrarr', + '\u2979': 'subrarr', + '\u297B': 'suplarr', + '\u297C': 'lfisht', + '\u297D': 'rfisht', + '\u297E': 'ufisht', + '\u297F': 'dfisht', + '\u299A': 'vzigzag', + '\u299C': 'vangrt', + '\u299D': 'angrtvbd', + '\u29A4': 'ange', + '\u29A5': 'range', + '\u29A6': 'dwangle', + '\u29A7': 'uwangle', + '\u29A8': 'angmsdaa', + '\u29A9': 'angmsdab', + '\u29AA': 'angmsdac', + '\u29AB': 'angmsdad', + '\u29AC': 'angmsdae', + '\u29AD': 'angmsdaf', + '\u29AE': 'angmsdag', + '\u29AF': 'angmsdah', + '\u29B0': 'bemptyv', + '\u29B1': 'demptyv', + '\u29B2': 'cemptyv', + '\u29B3': 'raemptyv', + '\u29B4': 'laemptyv', + '\u29B5': 'ohbar', + '\u29B6': 'omid', + '\u29B7': 'opar', + '\u29B9': 'operp', + '\u29BB': 'olcross', + '\u29BC': 'odsold', + '\u29BE': 'olcir', + '\u29BF': 'ofcir', + '\u29C0': 'olt', + '\u29C1': 'ogt', + '\u29C2': 'cirscir', + '\u29C3': 'cirE', + '\u29C4': 'solb', + '\u29C5': 'bsolb', + '\u29C9': 'boxbox', + '\u29CD': 'trisb', + '\u29CE': 'rtriltri', + '\u29CF': 'LeftTriangleBar', + '\u29CF̸': 'NotLeftTriangleBar', + '\u29D0': 'RightTriangleBar', + '\u29D0̸': 'NotRightTriangleBar', + '\u29DC': 'iinfin', + '\u29DD': 'infintie', + '\u29DE': 'nvinfin', + '\u29E3': 'eparsl', + '\u29E4': 'smeparsl', + '\u29E5': 'eqvparsl', + '\u29EB': 'lozf', + '\u29F4': 'RuleDelayed', + '\u29F6': 'dsol', + '\u2A00': 'xodot', + '\u2A01': 'xoplus', + '\u2A02': 'xotime', + '\u2A04': 'xuplus', + '\u2A06': 'xsqcup', + '\u2A0D': 'fpartint', + '\u2A10': 'cirfnint', + '\u2A11': 'awint', + '\u2A12': 'rppolint', + '\u2A13': 'scpolint', + '\u2A14': 'npolint', + '\u2A15': 'pointint', + '\u2A16': 'quatint', + '\u2A17': 'intlarhk', + '\u2A22': 'pluscir', + '\u2A23': 'plusacir', + '\u2A24': 'simplus', + '\u2A25': 'plusdu', + '\u2A26': 'plussim', + '\u2A27': 'plustwo', + '\u2A29': 'mcomma', + '\u2A2A': 'minusdu', + '\u2A2D': 'loplus', + '\u2A2E': 'roplus', + '\u2A2F': 'Cross', + '\u2A30': 'timesd', + '\u2A31': 'timesbar', + '\u2A33': 'smashp', + '\u2A34': 'lotimes', + '\u2A35': 'rotimes', + '\u2A36': 'otimesas', + '\u2A37': 'Otimes', + '\u2A38': 'odiv', + '\u2A39': 'triplus', + '\u2A3A': 'triminus', + '\u2A3B': 'tritime', + '\u2A3C': 'iprod', + '\u2A3F': 'amalg', + '\u2A40': 'capdot', + '\u2A42': 'ncup', + '\u2A43': 'ncap', + '\u2A44': 'capand', + '\u2A45': 'cupor', + '\u2A46': 'cupcap', + '\u2A47': 'capcup', + '\u2A48': 'cupbrcap', + '\u2A49': 'capbrcup', + '\u2A4A': 'cupcup', + '\u2A4B': 'capcap', + '\u2A4C': 'ccups', + '\u2A4D': 'ccaps', + '\u2A50': 'ccupssm', + '\u2A53': 'And', + '\u2A54': 'Or', + '\u2A55': 'andand', + '\u2A56': 'oror', + '\u2A57': 'orslope', + '\u2A58': 'andslope', + '\u2A5A': 'andv', + '\u2A5B': 'orv', + '\u2A5C': 'andd', + '\u2A5D': 'ord', + '\u2A5F': 'wedbar', + '\u2A66': 'sdote', + '\u2A6A': 'simdot', + '\u2A6D': 'congdot', + '\u2A6D̸': 'ncongdot', + '\u2A6E': 'easter', + '\u2A6F': 'apacir', + '\u2A70': 'apE', + '\u2A70̸': 'napE', + '\u2A71': 'eplus', + '\u2A72': 'pluse', + '\u2A73': 'Esim', + '\u2A77': 'eDDot', + '\u2A78': 'equivDD', + '\u2A79': 'ltcir', + '\u2A7A': 'gtcir', + '\u2A7B': 'ltquest', + '\u2A7C': 'gtquest', + '\u2A7D': 'les', + '\u2A7D̸': 'nles', + '\u2A7E': 'ges', + '\u2A7E̸': 'nges', + '\u2A7F': 'lesdot', + '\u2A80': 'gesdot', + '\u2A81': 'lesdoto', + '\u2A82': 'gesdoto', + '\u2A83': 'lesdotor', + '\u2A84': 'gesdotol', + '\u2A85': 'lap', + '\u2A86': 'gap', + '\u2A87': 'lne', + '\u2A88': 'gne', + '\u2A89': 'lnap', + '\u2A8A': 'gnap', + '\u2A8B': 'lEg', + '\u2A8C': 'gEl', + '\u2A8D': 'lsime', + '\u2A8E': 'gsime', + '\u2A8F': 'lsimg', + '\u2A90': 'gsiml', + '\u2A91': 'lgE', + '\u2A92': 'glE', + '\u2A93': 'lesges', + '\u2A94': 'gesles', + '\u2A95': 'els', + '\u2A96': 'egs', + '\u2A97': 'elsdot', + '\u2A98': 'egsdot', + '\u2A99': 'el', + '\u2A9A': 'eg', + '\u2A9D': 'siml', + '\u2A9E': 'simg', + '\u2A9F': 'simlE', + '\u2AA0': 'simgE', + '\u2AA1': 'LessLess', + '\u2AA1̸': 'NotNestedLessLess', + '\u2AA2': 'GreaterGreater', + '\u2AA2̸': 'NotNestedGreaterGreater', + '\u2AA4': 'glj', + '\u2AA5': 'gla', + '\u2AA6': 'ltcc', + '\u2AA7': 'gtcc', + '\u2AA8': 'lescc', + '\u2AA9': 'gescc', + '\u2AAA': 'smt', + '\u2AAB': 'lat', + '\u2AAC': 'smte', + '\u2AAC︀': 'smtes', + '\u2AAD': 'late', + '\u2AAD︀': 'lates', + '\u2AAE': 'bumpE', + '\u2AAF': 'pre', + '\u2AAF̸': 'npre', + '\u2AB0': 'sce', + '\u2AB0̸': 'nsce', + '\u2AB3': 'prE', + '\u2AB4': 'scE', + '\u2AB5': 'prnE', + '\u2AB6': 'scnE', + '\u2AB7': 'prap', + '\u2AB8': 'scap', + '\u2AB9': 'prnap', + '\u2ABA': 'scnap', + '\u2ABB': 'Pr', + '\u2ABC': 'Sc', + '\u2ABD': 'subdot', + '\u2ABE': 'supdot', + '\u2ABF': 'subplus', + '\u2AC0': 'supplus', + '\u2AC1': 'submult', + '\u2AC2': 'supmult', + '\u2AC3': 'subedot', + '\u2AC4': 'supedot', + '\u2AC5': 'subE', + '\u2AC5̸': 'nsubE', + '\u2AC6': 'supE', + '\u2AC6̸': 'nsupE', + '\u2AC7': 'subsim', + '\u2AC8': 'supsim', + '\u2ACB︀': 'vsubnE', + '\u2ACB': 'subnE', + '\u2ACC︀': 'vsupnE', + '\u2ACC': 'supnE', + '\u2ACF': 'csub', + '\u2AD0': 'csup', + '\u2AD1': 'csube', + '\u2AD2': 'csupe', + '\u2AD3': 'subsup', + '\u2AD4': 'supsub', + '\u2AD5': 'subsub', + '\u2AD6': 'supsup', + '\u2AD7': 'suphsub', + '\u2AD8': 'supdsub', + '\u2AD9': 'forkv', + '\u2ADA': 'topfork', + '\u2ADB': 'mlcp', + '\u2AE4': 'Dashv', + '\u2AE6': 'Vdashl', + '\u2AE7': 'Barv', + '\u2AE8': 'vBar', + '\u2AE9': 'vBarv', + '\u2AEB': 'Vbar', + '\u2AEC': 'Not', + '\u2AED': 'bNot', + '\u2AEE': 'rnmid', + '\u2AEF': 'cirmid', + '\u2AF0': 'midcir', + '\u2AF1': 'topcir', + '\u2AF2': 'nhpar', + '\u2AF3': 'parsim', + '\u2AFD': 'parsl', + '\u2AFD⃥': 'nparsl', + '\u266D': 'flat', + '\u266E': 'natur', + '\u266F': 'sharp', + '\xA4': 'curren', + '\xA2': 'cent', + '$': 'dollar', + '\xA3': 'pound', + '\xA5': 'yen', + '\u20AC': 'euro', + '\xB9': 'sup1', + '\xBD': 'half', + '\u2153': 'frac13', + '\xBC': 'frac14', + '\u2155': 'frac15', + '\u2159': 'frac16', + '\u215B': 'frac18', + '\xB2': 'sup2', + '\u2154': 'frac23', + '\u2156': 'frac25', + '\xB3': 'sup3', + '\xBE': 'frac34', + '\u2157': 'frac35', + '\u215C': 'frac38', + '\u2158': 'frac45', + '\u215A': 'frac56', + '\u215D': 'frac58', + '\u215E': 'frac78', + '\uD835\uDCB6': 'ascr', + '\uD835\uDD52': 'aopf', + '\uD835\uDD1E': 'afr', + '\uD835\uDD38': 'Aopf', + '\uD835\uDD04': 'Afr', + '\uD835\uDC9C': 'Ascr', + 'ª': 'ordf', + 'á': 'aacute', + 'Á': 'Aacute', + 'à': 'agrave', + 'À': 'Agrave', + 'ă': 'abreve', + 'Ă': 'Abreve', + 'â': 'acirc', + 'Â': 'Acirc', + 'å': 'aring', + 'Å': 'angst', + 'ä': 'auml', + 'Ä': 'Auml', + 'ã': 'atilde', + 'Ã': 'Atilde', + 'ą': 'aogon', + 'Ą': 'Aogon', + 'ā': 'amacr', + 'Ā': 'Amacr', + 'æ': 'aelig', + 'Æ': 'AElig', + '\uD835\uDCB7': 'bscr', + '\uD835\uDD53': 'bopf', + '\uD835\uDD1F': 'bfr', + '\uD835\uDD39': 'Bopf', + 'ℬ': 'Bscr', + '\uD835\uDD05': 'Bfr', + '\uD835\uDD20': 'cfr', + '\uD835\uDCB8': 'cscr', + '\uD835\uDD54': 'copf', + 'ℭ': 'Cfr', + '\uD835\uDC9E': 'Cscr', + 'ℂ': 'Copf', + 'ć': 'cacute', + 'Ć': 'Cacute', + 'ĉ': 'ccirc', + 'Ĉ': 'Ccirc', + 'č': 'ccaron', + 'Č': 'Ccaron', + 'ċ': 'cdot', + 'Ċ': 'Cdot', + 'ç': 'ccedil', + 'Ç': 'Ccedil', + '\u2105': 'incare', + '\uD835\uDD21': 'dfr', + 'ⅆ': 'dd', + '\uD835\uDD55': 'dopf', + '\uD835\uDCB9': 'dscr', + '\uD835\uDC9F': 'Dscr', + '\uD835\uDD07': 'Dfr', + 'ⅅ': 'DD', + '\uD835\uDD3B': 'Dopf', + 'ď': 'dcaron', + 'Ď': 'Dcaron', + 'đ': 'dstrok', + 'Đ': 'Dstrok', + 'ð': 'eth', + 'Ð': 'ETH', + 'ⅇ': 'ee', + 'ℯ': 'escr', + '\uD835\uDD22': 'efr', + '\uD835\uDD56': 'eopf', + 'ℰ': 'Escr', + '\uD835\uDD08': 'Efr', + '\uD835\uDD3C': 'Eopf', + 'é': 'eacute', + 'É': 'Eacute', + 'è': 'egrave', + 'È': 'Egrave', + 'ê': 'ecirc', + 'Ê': 'Ecirc', + 'ě': 'ecaron', + 'Ě': 'Ecaron', + 'ë': 'euml', + 'Ë': 'Euml', + 'ė': 'edot', + 'Ė': 'Edot', + 'ę': 'eogon', + 'Ę': 'Eogon', + 'ē': 'emacr', + 'Ē': 'Emacr', + '\uD835\uDD23': 'ffr', + '\uD835\uDD57': 'fopf', + '\uD835\uDCBB': 'fscr', + '\uD835\uDD09': 'Ffr', + '\uD835\uDD3D': 'Fopf', + 'ℱ': 'Fscr', + 'ff': 'fflig', + 'ffi': 'ffilig', + 'ffl': 'ffllig', + 'fi': 'filig', + 'fj': 'fjlig', + 'fl': 'fllig', + 'ƒ': 'fnof', + 'ℊ': 'gscr', + '\uD835\uDD58': 'gopf', + '\uD835\uDD24': 'gfr', + '\uD835\uDCA2': 'Gscr', + '\uD835\uDD3E': 'Gopf', + '\uD835\uDD0A': 'Gfr', + 'ǵ': 'gacute', + 'ğ': 'gbreve', + 'Ğ': 'Gbreve', + 'ĝ': 'gcirc', + 'Ĝ': 'Gcirc', + 'ġ': 'gdot', + 'Ġ': 'Gdot', + 'Ģ': 'Gcedil', + '\uD835\uDD25': 'hfr', + 'ℎ': 'planckh', + '\uD835\uDCBD': 'hscr', + '\uD835\uDD59': 'hopf', + 'ℋ': 'Hscr', + 'ℌ': 'Hfr', + 'ℍ': 'Hopf', + 'ĥ': 'hcirc', + 'Ĥ': 'Hcirc', + 'ℏ': 'hbar', + 'ħ': 'hstrok', + 'Ħ': 'Hstrok', + '\uD835\uDD5A': 'iopf', + '\uD835\uDD26': 'ifr', + '\uD835\uDCBE': 'iscr', + 'ⅈ': 'ii', + '\uD835\uDD40': 'Iopf', + 'ℐ': 'Iscr', + 'ℑ': 'Im', + 'í': 'iacute', + 'Í': 'Iacute', + 'ì': 'igrave', + 'Ì': 'Igrave', + 'î': 'icirc', + 'Î': 'Icirc', + 'ï': 'iuml', + 'Ï': 'Iuml', + 'ĩ': 'itilde', + 'Ĩ': 'Itilde', + 'İ': 'Idot', + 'į': 'iogon', + 'Į': 'Iogon', + 'ī': 'imacr', + 'Ī': 'Imacr', + 'ij': 'ijlig', + 'IJ': 'IJlig', + 'ı': 'imath', + '\uD835\uDCBF': 'jscr', + '\uD835\uDD5B': 'jopf', + '\uD835\uDD27': 'jfr', + '\uD835\uDCA5': 'Jscr', + '\uD835\uDD0D': 'Jfr', + '\uD835\uDD41': 'Jopf', + 'ĵ': 'jcirc', + 'Ĵ': 'Jcirc', + 'ȷ': 'jmath', + '\uD835\uDD5C': 'kopf', + '\uD835\uDCC0': 'kscr', + '\uD835\uDD28': 'kfr', + '\uD835\uDCA6': 'Kscr', + '\uD835\uDD42': 'Kopf', + '\uD835\uDD0E': 'Kfr', + 'ķ': 'kcedil', + 'Ķ': 'Kcedil', + '\uD835\uDD29': 'lfr', + '\uD835\uDCC1': 'lscr', + 'ℓ': 'ell', + '\uD835\uDD5D': 'lopf', + 'ℒ': 'Lscr', + '\uD835\uDD0F': 'Lfr', + '\uD835\uDD43': 'Lopf', + 'ĺ': 'lacute', + 'Ĺ': 'Lacute', + 'ľ': 'lcaron', + 'Ľ': 'Lcaron', + 'ļ': 'lcedil', + 'Ļ': 'Lcedil', + 'ł': 'lstrok', + 'Ł': 'Lstrok', + 'ŀ': 'lmidot', + 'Ŀ': 'Lmidot', + '\uD835\uDD2A': 'mfr', + '\uD835\uDD5E': 'mopf', + '\uD835\uDCC2': 'mscr', + '\uD835\uDD10': 'Mfr', + '\uD835\uDD44': 'Mopf', + 'ℳ': 'Mscr', + '\uD835\uDD2B': 'nfr', + '\uD835\uDD5F': 'nopf', + '\uD835\uDCC3': 'nscr', + 'ℕ': 'Nopf', + '\uD835\uDCA9': 'Nscr', + '\uD835\uDD11': 'Nfr', + 'ń': 'nacute', + 'Ń': 'Nacute', + 'ň': 'ncaron', + 'Ň': 'Ncaron', + 'ñ': 'ntilde', + 'Ñ': 'Ntilde', + 'ņ': 'ncedil', + 'Ņ': 'Ncedil', + '\u2116': 'numero', + 'ŋ': 'eng', + 'Ŋ': 'ENG', + '\uD835\uDD60': 'oopf', + '\uD835\uDD2C': 'ofr', + 'ℴ': 'oscr', + '\uD835\uDCAA': 'Oscr', + '\uD835\uDD12': 'Ofr', + '\uD835\uDD46': 'Oopf', + 'º': 'ordm', + 'ó': 'oacute', + 'Ó': 'Oacute', + 'ò': 'ograve', + 'Ò': 'Ograve', + 'ô': 'ocirc', + 'Ô': 'Ocirc', + 'ö': 'ouml', + 'Ö': 'Ouml', + 'ő': 'odblac', + 'Ő': 'Odblac', + 'õ': 'otilde', + 'Õ': 'Otilde', + 'ø': 'oslash', + 'Ø': 'Oslash', + 'ō': 'omacr', + 'Ō': 'Omacr', + 'œ': 'oelig', + 'Œ': 'OElig', + '\uD835\uDD2D': 'pfr', + '\uD835\uDCC5': 'pscr', + '\uD835\uDD61': 'popf', + 'ℙ': 'Popf', + '\uD835\uDD13': 'Pfr', + '\uD835\uDCAB': 'Pscr', + '\uD835\uDD62': 'qopf', + '\uD835\uDD2E': 'qfr', + '\uD835\uDCC6': 'qscr', + '\uD835\uDCAC': 'Qscr', + '\uD835\uDD14': 'Qfr', + 'ℚ': 'Qopf', + 'ĸ': 'kgreen', + '\uD835\uDD2F': 'rfr', + '\uD835\uDD63': 'ropf', + '\uD835\uDCC7': 'rscr', + 'ℛ': 'Rscr', + 'ℜ': 'Re', + 'ℝ': 'Ropf', + 'ŕ': 'racute', + 'Ŕ': 'Racute', + 'ř': 'rcaron', + 'Ř': 'Rcaron', + 'ŗ': 'rcedil', + 'Ŗ': 'Rcedil', + '\uD835\uDD64': 'sopf', + '\uD835\uDCC8': 'sscr', + '\uD835\uDD30': 'sfr', + '\uD835\uDD4A': 'Sopf', + '\uD835\uDD16': 'Sfr', + '\uD835\uDCAE': 'Sscr', + '\u24C8': 'oS', + 'ś': 'sacute', + 'Ś': 'Sacute', + 'ŝ': 'scirc', + 'Ŝ': 'Scirc', + 'š': 'scaron', + 'Š': 'Scaron', + 'ş': 'scedil', + 'Ş': 'Scedil', + 'ß': 'szlig', + '\uD835\uDD31': 'tfr', + '\uD835\uDCC9': 'tscr', + '\uD835\uDD65': 'topf', + '\uD835\uDCAF': 'Tscr', + '\uD835\uDD17': 'Tfr', + '\uD835\uDD4B': 'Topf', + 'ť': 'tcaron', + 'Ť': 'Tcaron', + 'ţ': 'tcedil', + 'Ţ': 'Tcedil', + '\u2122': 'trade', + 'ŧ': 'tstrok', + 'Ŧ': 'Tstrok', + '\uD835\uDCCA': 'uscr', + '\uD835\uDD66': 'uopf', + '\uD835\uDD32': 'ufr', + '\uD835\uDD4C': 'Uopf', + '\uD835\uDD18': 'Ufr', + '\uD835\uDCB0': 'Uscr', + 'ú': 'uacute', + 'Ú': 'Uacute', + 'ù': 'ugrave', + 'Ù': 'Ugrave', + 'ŭ': 'ubreve', + 'Ŭ': 'Ubreve', + 'û': 'ucirc', + 'Û': 'Ucirc', + 'ů': 'uring', + 'Ů': 'Uring', + 'ü': 'uuml', + 'Ü': 'Uuml', + 'ű': 'udblac', + 'Ű': 'Udblac', + 'ũ': 'utilde', + 'Ũ': 'Utilde', + 'ų': 'uogon', + 'Ų': 'Uogon', + 'ū': 'umacr', + 'Ū': 'Umacr', + '\uD835\uDD33': 'vfr', + '\uD835\uDD67': 'vopf', + '\uD835\uDCCB': 'vscr', + '\uD835\uDD19': 'Vfr', + '\uD835\uDD4D': 'Vopf', + '\uD835\uDCB1': 'Vscr', + '\uD835\uDD68': 'wopf', + '\uD835\uDCCC': 'wscr', + '\uD835\uDD34': 'wfr', + '\uD835\uDCB2': 'Wscr', + '\uD835\uDD4E': 'Wopf', + '\uD835\uDD1A': 'Wfr', + 'ŵ': 'wcirc', + 'Ŵ': 'Wcirc', + '\uD835\uDD35': 'xfr', + '\uD835\uDCCD': 'xscr', + '\uD835\uDD69': 'xopf', + '\uD835\uDD4F': 'Xopf', + '\uD835\uDD1B': 'Xfr', + '\uD835\uDCB3': 'Xscr', + '\uD835\uDD36': 'yfr', + '\uD835\uDCCE': 'yscr', + '\uD835\uDD6A': 'yopf', + '\uD835\uDCB4': 'Yscr', + '\uD835\uDD1C': 'Yfr', + '\uD835\uDD50': 'Yopf', + 'ý': 'yacute', + 'Ý': 'Yacute', + 'ŷ': 'ycirc', + 'Ŷ': 'Ycirc', + 'ÿ': 'yuml', + 'Ÿ': 'Yuml', + '\uD835\uDCCF': 'zscr', + '\uD835\uDD37': 'zfr', + '\uD835\uDD6B': 'zopf', + 'ℨ': 'Zfr', + 'ℤ': 'Zopf', + '\uD835\uDCB5': 'Zscr', + 'ź': 'zacute', + 'Ź': 'Zacute', + 'ž': 'zcaron', + 'Ž': 'Zcaron', + 'ż': 'zdot', + 'Ż': 'Zdot', + 'Ƶ': 'imped', + 'þ': 'thorn', + 'Þ': 'THORN', + 'ʼn': 'napos', + 'α': 'alpha', + 'Α': 'Alpha', + 'β': 'beta', + 'Β': 'Beta', + 'γ': 'gamma', + 'Γ': 'Gamma', + 'δ': 'delta', + 'Δ': 'Delta', + 'ε': 'epsi', + 'ϵ': 'epsiv', + 'Ε': 'Epsilon', + 'ϝ': 'gammad', + 'Ϝ': 'Gammad', + 'ζ': 'zeta', + 'Ζ': 'Zeta', + 'η': 'eta', + 'Η': 'Eta', + 'θ': 'theta', + 'ϑ': 'thetav', + 'Θ': 'Theta', + 'ι': 'iota', + 'Ι': 'Iota', + 'κ': 'kappa', + 'ϰ': 'kappav', + 'Κ': 'Kappa', + 'λ': 'lambda', + 'Λ': 'Lambda', + 'μ': 'mu', + 'µ': 'micro', + 'Μ': 'Mu', + 'ν': 'nu', + 'Ν': 'Nu', + 'ξ': 'xi', + 'Ξ': 'Xi', + 'ο': 'omicron', + 'Ο': 'Omicron', + 'π': 'pi', + 'ϖ': 'piv', + 'Π': 'Pi', + 'ρ': 'rho', + 'ϱ': 'rhov', + 'Ρ': 'Rho', + 'σ': 'sigma', + 'Σ': 'Sigma', + 'ς': 'sigmaf', + 'τ': 'tau', + 'Τ': 'Tau', + 'υ': 'upsi', + 'Υ': 'Upsilon', + 'ϒ': 'Upsi', + 'φ': 'phi', + 'ϕ': 'phiv', + 'Φ': 'Phi', + 'χ': 'chi', + 'Χ': 'Chi', + 'ψ': 'psi', + 'Ψ': 'Psi', + 'ω': 'omega', + 'Ω': 'ohm', + 'а': 'acy', + 'А': 'Acy', + 'б': 'bcy', + 'Б': 'Bcy', + 'в': 'vcy', + 'В': 'Vcy', + 'г': 'gcy', + 'Г': 'Gcy', + 'ѓ': 'gjcy', + 'Ѓ': 'GJcy', + 'д': 'dcy', + 'Д': 'Dcy', + 'ђ': 'djcy', + 'Ђ': 'DJcy', + 'е': 'iecy', + 'Е': 'IEcy', + 'ё': 'iocy', + 'Ё': 'IOcy', + 'є': 'jukcy', + 'Є': 'Jukcy', + 'ж': 'zhcy', + 'Ж': 'ZHcy', + 'з': 'zcy', + 'З': 'Zcy', + 'ѕ': 'dscy', + 'Ѕ': 'DScy', + 'и': 'icy', + 'И': 'Icy', + 'і': 'iukcy', + 'І': 'Iukcy', + 'ї': 'yicy', + 'Ї': 'YIcy', + 'й': 'jcy', + 'Й': 'Jcy', + 'ј': 'jsercy', + 'Ј': 'Jsercy', + 'к': 'kcy', + 'К': 'Kcy', + 'ќ': 'kjcy', + 'Ќ': 'KJcy', + 'л': 'lcy', + 'Л': 'Lcy', + 'љ': 'ljcy', + 'Љ': 'LJcy', + 'м': 'mcy', + 'М': 'Mcy', + 'н': 'ncy', + 'Н': 'Ncy', + 'њ': 'njcy', + 'Њ': 'NJcy', + 'о': 'ocy', + 'О': 'Ocy', + 'п': 'pcy', + 'П': 'Pcy', + 'р': 'rcy', + 'Р': 'Rcy', + 'с': 'scy', + 'С': 'Scy', + 'т': 'tcy', + 'Т': 'Tcy', + 'ћ': 'tshcy', + 'Ћ': 'TSHcy', + 'у': 'ucy', + 'У': 'Ucy', + 'ў': 'ubrcy', + 'Ў': 'Ubrcy', + 'ф': 'fcy', + 'Ф': 'Fcy', + 'х': 'khcy', + 'Х': 'KHcy', + 'ц': 'tscy', + 'Ц': 'TScy', + 'ч': 'chcy', + 'Ч': 'CHcy', + 'џ': 'dzcy', + 'Џ': 'DZcy', + 'ш': 'shcy', + 'Ш': 'SHcy', + 'щ': 'shchcy', + 'Щ': 'SHCHcy', + 'ъ': 'hardcy', + 'Ъ': 'HARDcy', + 'ы': 'ycy', + 'Ы': 'Ycy', + 'ь': 'softcy', + 'Ь': 'SOFTcy', + 'э': 'ecy', + 'Э': 'Ecy', + 'ю': 'yucy', + 'Ю': 'YUcy', + 'я': 'yacy', + 'Я': 'YAcy', + 'ℵ': 'aleph', + 'ℶ': 'beth', + 'ℷ': 'gimel', + 'ℸ': 'daleth' + }; + var regexEscape = /["&'<>`]/g; + var escapeMap = { + '"': '"', + '&': '&', + '\'': ''', + '<': '<', + '>': '>', + '`': '`' + }; + var regexInvalidEntity = /&#(?:[xX][^a-fA-F0-9]|[^0-9xX])/; + var regexInvalidRawCodePoint = /[\0-\x08\x0B\x0E-\x1F\x7F-\x9F\uFDD0-\uFDEF\uFFFE\uFFFF]|[\uD83F\uD87F\uD8BF\uD8FF\uD93F\uD97F\uD9BF\uD9FF\uDA3F\uDA7F\uDABF\uDAFF\uDB3F\uDB7F\uDBBF\uDBFF][\uDFFE\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/; + var regexDecode = /&(CounterClockwiseContourIntegral|DoubleLongLeftRightArrow|ClockwiseContourIntegral|NotNestedGreaterGreater|NotSquareSupersetEqual|DiacriticalDoubleAcute|NotRightTriangleEqual|NotSucceedsSlantEqual|NotPrecedesSlantEqual|CloseCurlyDoubleQuote|NegativeVeryThinSpace|DoubleContourIntegral|FilledVerySmallSquare|CapitalDifferentialD|OpenCurlyDoubleQuote|EmptyVerySmallSquare|NestedGreaterGreater|DoubleLongRightArrow|NotLeftTriangleEqual|NotGreaterSlantEqual|ReverseUpEquilibrium|DoubleLeftRightArrow|NotSquareSubsetEqual|NotDoubleVerticalBar|RightArrowLeftArrow|NotGreaterFullEqual|NotRightTriangleBar|SquareSupersetEqual|DownLeftRightVector|DoubleLongLeftArrow|leftrightsquigarrow|LeftArrowRightArrow|NegativeMediumSpace|blacktriangleright|RightDownVectorBar|PrecedesSlantEqual|RightDoubleBracket|SucceedsSlantEqual|NotLeftTriangleBar|RightTriangleEqual|SquareIntersection|RightDownTeeVector|ReverseEquilibrium|NegativeThickSpace|longleftrightarrow|Longleftrightarrow|LongLeftRightArrow|DownRightTeeVector|DownRightVectorBar|GreaterSlantEqual|SquareSubsetEqual|LeftDownVectorBar|LeftDoubleBracket|VerticalSeparator|rightleftharpoons|NotGreaterGreater|NotSquareSuperset|blacktriangleleft|blacktriangledown|NegativeThinSpace|LeftDownTeeVector|NotLessSlantEqual|leftrightharpoons|DoubleUpDownArrow|DoubleVerticalBar|LeftTriangleEqual|FilledSmallSquare|twoheadrightarrow|NotNestedLessLess|DownLeftTeeVector|DownLeftVectorBar|RightAngleBracket|NotTildeFullEqual|NotReverseElement|RightUpDownVector|DiacriticalTilde|NotSucceedsTilde|circlearrowright|NotPrecedesEqual|rightharpoondown|DoubleRightArrow|NotSucceedsEqual|NonBreakingSpace|NotRightTriangle|LessEqualGreater|RightUpTeeVector|LeftAngleBracket|GreaterFullEqual|DownArrowUpArrow|RightUpVectorBar|twoheadleftarrow|GreaterEqualLess|downharpoonright|RightTriangleBar|ntrianglerighteq|NotSupersetEqual|LeftUpDownVector|DiacriticalAcute|rightrightarrows|vartriangleright|UpArrowDownArrow|DiacriticalGrave|UnderParenthesis|EmptySmallSquare|LeftUpVectorBar|leftrightarrows|DownRightVector|downharpoonleft|trianglerighteq|ShortRightArrow|OverParenthesis|DoubleLeftArrow|DoubleDownArrow|NotSquareSubset|bigtriangledown|ntrianglelefteq|UpperRightArrow|curvearrowright|vartriangleleft|NotLeftTriangle|nleftrightarrow|LowerRightArrow|NotHumpDownHump|NotGreaterTilde|rightthreetimes|LeftUpTeeVector|NotGreaterEqual|straightepsilon|LeftTriangleBar|rightsquigarrow|ContourIntegral|rightleftarrows|CloseCurlyQuote|RightDownVector|LeftRightVector|nLeftrightarrow|leftharpoondown|circlearrowleft|SquareSuperset|OpenCurlyQuote|hookrightarrow|HorizontalLine|DiacriticalDot|NotLessGreater|ntriangleright|DoubleRightTee|InvisibleComma|InvisibleTimes|LowerLeftArrow|DownLeftVector|NotSubsetEqual|curvearrowleft|trianglelefteq|NotVerticalBar|TildeFullEqual|downdownarrows|NotGreaterLess|RightTeeVector|ZeroWidthSpace|looparrowright|LongRightArrow|doublebarwedge|ShortLeftArrow|ShortDownArrow|RightVectorBar|GreaterGreater|ReverseElement|rightharpoonup|LessSlantEqual|leftthreetimes|upharpoonright|rightarrowtail|LeftDownVector|Longrightarrow|NestedLessLess|UpperLeftArrow|nshortparallel|leftleftarrows|leftrightarrow|Leftrightarrow|LeftRightArrow|longrightarrow|upharpoonleft|RightArrowBar|ApplyFunction|LeftTeeVector|leftarrowtail|NotEqualTilde|varsubsetneqq|varsupsetneqq|RightTeeArrow|SucceedsEqual|SucceedsTilde|LeftVectorBar|SupersetEqual|hookleftarrow|DifferentialD|VerticalTilde|VeryThinSpace|blacktriangle|bigtriangleup|LessFullEqual|divideontimes|leftharpoonup|UpEquilibrium|ntriangleleft|RightTriangle|measuredangle|shortparallel|longleftarrow|Longleftarrow|LongLeftArrow|DoubleLeftTee|Poincareplane|PrecedesEqual|triangleright|DoubleUpArrow|RightUpVector|fallingdotseq|looparrowleft|PrecedesTilde|NotTildeEqual|NotTildeTilde|smallsetminus|Proportional|triangleleft|triangledown|UnderBracket|NotHumpEqual|exponentiale|ExponentialE|NotLessTilde|HilbertSpace|RightCeiling|blacklozenge|varsupsetneq|HumpDownHump|GreaterEqual|VerticalLine|LeftTeeArrow|NotLessEqual|DownTeeArrow|LeftTriangle|varsubsetneq|Intersection|NotCongruent|DownArrowBar|LeftUpVector|LeftArrowBar|risingdotseq|GreaterTilde|RoundImplies|SquareSubset|ShortUpArrow|NotSuperset|quaternions|precnapprox|backepsilon|preccurlyeq|OverBracket|blacksquare|MediumSpace|VerticalBar|circledcirc|circleddash|CircleMinus|CircleTimes|LessGreater|curlyeqprec|curlyeqsucc|diamondsuit|UpDownArrow|Updownarrow|RuleDelayed|Rrightarrow|updownarrow|RightVector|nRightarrow|nrightarrow|eqslantless|LeftCeiling|Equilibrium|SmallCircle|expectation|NotSucceeds|thickapprox|GreaterLess|SquareUnion|NotPrecedes|NotLessLess|straightphi|succnapprox|succcurlyeq|SubsetEqual|sqsupseteq|Proportion|Laplacetrf|ImaginaryI|supsetneqq|NotGreater|gtreqqless|NotElement|ThickSpace|TildeEqual|TildeTilde|Fouriertrf|rmoustache|EqualTilde|eqslantgtr|UnderBrace|LeftVector|UpArrowBar|nLeftarrow|nsubseteqq|subsetneqq|nsupseteqq|nleftarrow|succapprox|lessapprox|UpTeeArrow|upuparrows|curlywedge|lesseqqgtr|varepsilon|varnothing|RightFloor|complement|CirclePlus|sqsubseteq|Lleftarrow|circledast|RightArrow|Rightarrow|rightarrow|lmoustache|Bernoullis|precapprox|mapstoleft|mapstodown|longmapsto|dotsquare|downarrow|DoubleDot|nsubseteq|supsetneq|leftarrow|nsupseteq|subsetneq|ThinSpace|ngeqslant|subseteqq|HumpEqual|NotSubset|triangleq|NotCupCap|lesseqgtr|heartsuit|TripleDot|Leftarrow|Coproduct|Congruent|varpropto|complexes|gvertneqq|LeftArrow|LessTilde|supseteqq|MinusPlus|CircleDot|nleqslant|NotExists|gtreqless|nparallel|UnionPlus|LeftFloor|checkmark|CenterDot|centerdot|Mellintrf|gtrapprox|bigotimes|OverBrace|spadesuit|therefore|pitchfork|rationals|PlusMinus|Backslash|Therefore|DownBreve|backsimeq|backprime|DownArrow|nshortmid|Downarrow|lvertneqq|eqvparsl|imagline|imagpart|infintie|integers|Integral|intercal|LessLess|Uarrocir|intlarhk|sqsupset|angmsdaf|sqsubset|llcorner|vartheta|cupbrcap|lnapprox|Superset|SuchThat|succnsim|succneqq|angmsdag|biguplus|curlyvee|trpezium|Succeeds|NotTilde|bigwedge|angmsdah|angrtvbd|triminus|cwconint|fpartint|lrcorner|smeparsl|subseteq|urcorner|lurdshar|laemptyv|DDotrahd|approxeq|ldrushar|awconint|mapstoup|backcong|shortmid|triangle|geqslant|gesdotol|timesbar|circledR|circledS|setminus|multimap|naturals|scpolint|ncongdot|RightTee|boxminus|gnapprox|boxtimes|andslope|thicksim|angmsdaa|varsigma|cirfnint|rtriltri|angmsdab|rppolint|angmsdac|barwedge|drbkarow|clubsuit|thetasym|bsolhsub|capbrcup|dzigrarr|doteqdot|DotEqual|dotminus|UnderBar|NotEqual|realpart|otimesas|ulcorner|hksearow|hkswarow|parallel|PartialD|elinters|emptyset|plusacir|bbrktbrk|angmsdad|pointint|bigoplus|angmsdae|Precedes|bigsqcup|varkappa|notindot|supseteq|precneqq|precnsim|profalar|profline|profsurf|leqslant|lesdotor|raemptyv|subplus|notnivb|notnivc|subrarr|zigrarr|vzigzag|submult|subedot|Element|between|cirscir|larrbfs|larrsim|lotimes|lbrksld|lbrkslu|lozenge|ldrdhar|dbkarow|bigcirc|epsilon|simrarr|simplus|ltquest|Epsilon|luruhar|gtquest|maltese|npolint|eqcolon|npreceq|bigodot|ddagger|gtrless|bnequiv|harrcir|ddotseq|equivDD|backsim|demptyv|nsqsube|nsqsupe|Upsilon|nsubset|upsilon|minusdu|nsucceq|swarrow|nsupset|coloneq|searrow|boxplus|napprox|natural|asympeq|alefsym|congdot|nearrow|bigstar|diamond|supplus|tritime|LeftTee|nvinfin|triplus|NewLine|nvltrie|nvrtrie|nwarrow|nexists|Diamond|ruluhar|Implies|supmult|angzarr|suplarr|suphsub|questeq|because|digamma|Because|olcross|bemptyv|omicron|Omicron|rotimes|NoBreak|intprod|angrtvb|orderof|uwangle|suphsol|lesdoto|orslope|DownTee|realine|cudarrl|rdldhar|OverBar|supedot|lessdot|supdsub|topfork|succsim|rbrkslu|rbrksld|pertenk|cudarrr|isindot|planckh|lessgtr|pluscir|gesdoto|plussim|plustwo|lesssim|cularrp|rarrsim|Cayleys|notinva|notinvb|notinvc|UpArrow|Uparrow|uparrow|NotLess|dwangle|precsim|Product|curarrm|Cconint|dotplus|rarrbfs|ccupssm|Cedilla|cemptyv|notniva|quatint|frac35|frac38|frac45|frac56|frac58|frac78|tridot|xoplus|gacute|gammad|Gammad|lfisht|lfloor|bigcup|sqsupe|gbreve|Gbreve|lharul|sqsube|sqcups|Gcedil|apacir|llhard|lmidot|Lmidot|lmoust|andand|sqcaps|approx|Abreve|spades|circeq|tprime|divide|topcir|Assign|topbot|gesdot|divonx|xuplus|timesd|gesles|atilde|solbar|SOFTcy|loplus|timesb|lowast|lowbar|dlcorn|dlcrop|softcy|dollar|lparlt|thksim|lrhard|Atilde|lsaquo|smashp|bigvee|thinsp|wreath|bkarow|lsquor|lstrok|Lstrok|lthree|ltimes|ltlarr|DotDot|simdot|ltrPar|weierp|xsqcup|angmsd|sigmav|sigmaf|zeetrf|Zcaron|zcaron|mapsto|vsupne|thetav|cirmid|marker|mcomma|Zacute|vsubnE|there4|gtlPar|vsubne|bottom|gtrarr|SHCHcy|shchcy|midast|midcir|middot|minusb|minusd|gtrdot|bowtie|sfrown|mnplus|models|colone|seswar|Colone|mstpos|searhk|gtrsim|nacute|Nacute|boxbox|telrec|hairsp|Tcedil|nbumpe|scnsim|ncaron|Ncaron|ncedil|Ncedil|hamilt|Scedil|nearhk|hardcy|HARDcy|tcedil|Tcaron|commat|nequiv|nesear|tcaron|target|hearts|nexist|varrho|scedil|Scaron|scaron|hellip|Sacute|sacute|hercon|swnwar|compfn|rtimes|rthree|rsquor|rsaquo|zacute|wedgeq|homtht|barvee|barwed|Barwed|rpargt|horbar|conint|swarhk|roplus|nltrie|hslash|hstrok|Hstrok|rmoust|Conint|bprime|hybull|hyphen|iacute|Iacute|supsup|supsub|supsim|varphi|coprod|brvbar|agrave|Supset|supset|igrave|Igrave|notinE|Agrave|iiiint|iinfin|copysr|wedbar|Verbar|vangrt|becaus|incare|verbar|inodot|bullet|drcorn|intcal|drcrop|cularr|vellip|Utilde|bumpeq|cupcap|dstrok|Dstrok|CupCap|cupcup|cupdot|eacute|Eacute|supdot|iquest|easter|ecaron|Ecaron|ecolon|isinsv|utilde|itilde|Itilde|curarr|succeq|Bumpeq|cacute|ulcrop|nparsl|Cacute|nprcue|egrave|Egrave|nrarrc|nrarrw|subsup|subsub|nrtrie|jsercy|nsccue|Jsercy|kappav|kcedil|Kcedil|subsim|ulcorn|nsimeq|egsdot|veebar|kgreen|capand|elsdot|Subset|subset|curren|aacute|lacute|Lacute|emptyv|ntilde|Ntilde|lagran|lambda|Lambda|capcap|Ugrave|langle|subdot|emsp13|numero|emsp14|nvdash|nvDash|nVdash|nVDash|ugrave|ufisht|nvHarr|larrfs|nvlArr|larrhk|larrlp|larrpl|nvrArr|Udblac|nwarhk|larrtl|nwnear|oacute|Oacute|latail|lAtail|sstarf|lbrace|odblac|Odblac|lbrack|udblac|odsold|eparsl|lcaron|Lcaron|ograve|Ograve|lcedil|Lcedil|Aacute|ssmile|ssetmn|squarf|ldquor|capcup|ominus|cylcty|rharul|eqcirc|dagger|rfloor|rfisht|Dagger|daleth|equals|origof|capdot|equest|dcaron|Dcaron|rdquor|oslash|Oslash|otilde|Otilde|otimes|Otimes|urcrop|Ubreve|ubreve|Yacute|Uacute|uacute|Rcedil|rcedil|urcorn|parsim|Rcaron|Vdashl|rcaron|Tstrok|percnt|period|permil|Exists|yacute|rbrack|rbrace|phmmat|ccaron|Ccaron|planck|ccedil|plankv|tstrok|female|plusdo|plusdu|ffilig|plusmn|ffllig|Ccedil|rAtail|dfisht|bernou|ratail|Rarrtl|rarrtl|angsph|rarrpl|rarrlp|rarrhk|xwedge|xotime|forall|ForAll|Vvdash|vsupnE|preceq|bigcap|frac12|frac13|frac14|primes|rarrfs|prnsim|frac15|Square|frac16|square|lesdot|frac18|frac23|propto|prurel|rarrap|rangle|puncsp|frac25|Racute|qprime|racute|lesges|frac34|abreve|AElig|eqsim|utdot|setmn|urtri|Equal|Uring|seArr|uring|searr|dashv|Dashv|mumap|nabla|iogon|Iogon|sdote|sdotb|scsim|napid|napos|equiv|natur|Acirc|dblac|erarr|nbump|iprod|erDot|ucirc|awint|esdot|angrt|ncong|isinE|scnap|Scirc|scirc|ndash|isins|Ubrcy|nearr|neArr|isinv|nedot|ubrcy|acute|Ycirc|iukcy|Iukcy|xutri|nesim|caret|jcirc|Jcirc|caron|twixt|ddarr|sccue|exist|jmath|sbquo|ngeqq|angst|ccaps|lceil|ngsim|UpTee|delta|Delta|rtrif|nharr|nhArr|nhpar|rtrie|jukcy|Jukcy|kappa|rsquo|Kappa|nlarr|nlArr|TSHcy|rrarr|aogon|Aogon|fflig|xrarr|tshcy|ccirc|nleqq|filig|upsih|nless|dharl|nlsim|fjlig|ropar|nltri|dharr|robrk|roarr|fllig|fltns|roang|rnmid|subnE|subne|lAarr|trisb|Ccirc|acirc|ccups|blank|VDash|forkv|Vdash|langd|cedil|blk12|blk14|laquo|strns|diams|notin|vDash|larrb|blk34|block|disin|uplus|vdash|vBarv|aelig|starf|Wedge|check|xrArr|lates|lbarr|lBarr|notni|lbbrk|bcong|frasl|lbrke|frown|vrtri|vprop|vnsup|gamma|Gamma|wedge|xodot|bdquo|srarr|doteq|ldquo|boxdl|boxdL|gcirc|Gcirc|boxDl|boxDL|boxdr|boxdR|boxDr|TRADE|trade|rlhar|boxDR|vnsub|npart|vltri|rlarr|boxhd|boxhD|nprec|gescc|nrarr|nrArr|boxHd|boxHD|boxhu|boxhU|nrtri|boxHu|clubs|boxHU|times|colon|Colon|gimel|xlArr|Tilde|nsime|tilde|nsmid|nspar|THORN|thorn|xlarr|nsube|nsubE|thkap|xhArr|comma|nsucc|boxul|boxuL|nsupe|nsupE|gneqq|gnsim|boxUl|boxUL|grave|boxur|boxuR|boxUr|boxUR|lescc|angle|bepsi|boxvh|varpi|boxvH|numsp|Theta|gsime|gsiml|theta|boxVh|boxVH|boxvl|gtcir|gtdot|boxvL|boxVl|boxVL|crarr|cross|Cross|nvsim|boxvr|nwarr|nwArr|sqsup|dtdot|Uogon|lhard|lharu|dtrif|ocirc|Ocirc|lhblk|duarr|odash|sqsub|Hacek|sqcup|llarr|duhar|oelig|OElig|ofcir|boxvR|uogon|lltri|boxVr|csube|uuarr|ohbar|csupe|ctdot|olarr|olcir|harrw|oline|sqcap|omacr|Omacr|omega|Omega|boxVR|aleph|lneqq|lnsim|loang|loarr|rharu|lobrk|hcirc|operp|oplus|rhard|Hcirc|orarr|Union|order|ecirc|Ecirc|cuepr|szlig|cuesc|breve|reals|eDDot|Breve|hoarr|lopar|utrif|rdquo|Umacr|umacr|efDot|swArr|ultri|alpha|rceil|ovbar|swarr|Wcirc|wcirc|smtes|smile|bsemi|lrarr|aring|parsl|lrhar|bsime|uhblk|lrtri|cupor|Aring|uharr|uharl|slarr|rbrke|bsolb|lsime|rbbrk|RBarr|lsimg|phone|rBarr|rbarr|icirc|lsquo|Icirc|emacr|Emacr|ratio|simne|plusb|simlE|simgE|simeq|pluse|ltcir|ltdot|empty|xharr|xdtri|iexcl|Alpha|ltrie|rarrw|pound|ltrif|xcirc|bumpe|prcue|bumpE|asymp|amacr|cuvee|Sigma|sigma|iiint|udhar|iiota|ijlig|IJlig|supnE|imacr|Imacr|prime|Prime|image|prnap|eogon|Eogon|rarrc|mdash|mDDot|cuwed|imath|supne|imped|Amacr|udarr|prsim|micro|rarrb|cwint|raquo|infin|eplus|range|rangd|Ucirc|radic|minus|amalg|veeeq|rAarr|epsiv|ycirc|quest|sharp|quot|zwnj|Qscr|race|qscr|Qopf|qopf|qint|rang|Rang|Zscr|zscr|Zopf|zopf|rarr|rArr|Rarr|Pscr|pscr|prop|prod|prnE|prec|ZHcy|zhcy|prap|Zeta|zeta|Popf|popf|Zdot|plus|zdot|Yuml|yuml|phiv|YUcy|yucy|Yscr|yscr|perp|Yopf|yopf|part|para|YIcy|Ouml|rcub|yicy|YAcy|rdca|ouml|osol|Oscr|rdsh|yacy|real|oscr|xvee|andd|rect|andv|Xscr|oror|ordm|ordf|xscr|ange|aopf|Aopf|rHar|Xopf|opar|Oopf|xopf|xnis|rhov|oopf|omid|xmap|oint|apid|apos|ogon|ascr|Ascr|odot|odiv|xcup|xcap|ocir|oast|nvlt|nvle|nvgt|nvge|nvap|Wscr|wscr|auml|ntlg|ntgl|nsup|nsub|nsim|Nscr|nscr|nsce|Wopf|ring|npre|wopf|npar|Auml|Barv|bbrk|Nopf|nopf|nmid|nLtv|beta|ropf|Ropf|Beta|beth|nles|rpar|nleq|bnot|bNot|nldr|NJcy|rscr|Rscr|Vscr|vscr|rsqb|njcy|bopf|nisd|Bopf|rtri|Vopf|nGtv|ngtr|vopf|boxh|boxH|boxv|nges|ngeq|boxV|bscr|scap|Bscr|bsim|Vert|vert|bsol|bull|bump|caps|cdot|ncup|scnE|ncap|nbsp|napE|Cdot|cent|sdot|Vbar|nang|vBar|chcy|Mscr|mscr|sect|semi|CHcy|Mopf|mopf|sext|circ|cire|mldr|mlcp|cirE|comp|shcy|SHcy|vArr|varr|cong|copf|Copf|copy|COPY|malt|male|macr|lvnE|cscr|ltri|sime|ltcc|simg|Cscr|siml|csub|Uuml|lsqb|lsim|uuml|csup|Lscr|lscr|utri|smid|lpar|cups|smte|lozf|darr|Lopf|Uscr|solb|lopf|sopf|Sopf|lneq|uscr|spar|dArr|lnap|Darr|dash|Sqrt|LJcy|ljcy|lHar|dHar|Upsi|upsi|diam|lesg|djcy|DJcy|leqq|dopf|Dopf|dscr|Dscr|dscy|ldsh|ldca|squf|DScy|sscr|Sscr|dsol|lcub|late|star|Star|Uopf|Larr|lArr|larr|uopf|dtri|dzcy|sube|subE|Lang|lang|Kscr|kscr|Kopf|kopf|KJcy|kjcy|KHcy|khcy|DZcy|ecir|edot|eDot|Jscr|jscr|succ|Jopf|jopf|Edot|uHar|emsp|ensp|Iuml|iuml|eopf|isin|Iscr|iscr|Eopf|epar|sung|epsi|escr|sup1|sup2|sup3|Iota|iota|supe|supE|Iopf|iopf|IOcy|iocy|Escr|esim|Esim|imof|Uarr|QUOT|uArr|uarr|euml|IEcy|iecy|Idot|Euml|euro|excl|Hscr|hscr|Hopf|hopf|TScy|tscy|Tscr|hbar|tscr|flat|tbrk|fnof|hArr|harr|half|fopf|Fopf|tdot|gvnE|fork|trie|gtcc|fscr|Fscr|gdot|gsim|Gscr|gscr|Gopf|gopf|gneq|Gdot|tosa|gnap|Topf|topf|geqq|toea|GJcy|gjcy|tint|gesl|mid|Sfr|ggg|top|ges|gla|glE|glj|geq|gne|gEl|gel|gnE|Gcy|gcy|gap|Tfr|tfr|Tcy|tcy|Hat|Tau|Ffr|tau|Tab|hfr|Hfr|ffr|Fcy|fcy|icy|Icy|iff|ETH|eth|ifr|Ifr|Eta|eta|int|Int|Sup|sup|ucy|Ucy|Sum|sum|jcy|ENG|ufr|Ufr|eng|Jcy|jfr|els|ell|egs|Efr|efr|Jfr|uml|kcy|Kcy|Ecy|ecy|kfr|Kfr|lap|Sub|sub|lat|lcy|Lcy|leg|Dot|dot|lEg|leq|les|squ|div|die|lfr|Lfr|lgE|Dfr|dfr|Del|deg|Dcy|dcy|lne|lnE|sol|loz|smt|Cup|lrm|cup|lsh|Lsh|sim|shy|map|Map|mcy|Mcy|mfr|Mfr|mho|gfr|Gfr|sfr|cir|Chi|chi|nap|Cfr|vcy|Vcy|cfr|Scy|scy|ncy|Ncy|vee|Vee|Cap|cap|nfr|scE|sce|Nfr|nge|ngE|nGg|vfr|Vfr|ngt|bot|nGt|nis|niv|Rsh|rsh|nle|nlE|bne|Bfr|bfr|nLl|nlt|nLt|Bcy|bcy|not|Not|rlm|wfr|Wfr|npr|nsc|num|ocy|ast|Ocy|ofr|xfr|Xfr|Ofr|ogt|ohm|apE|olt|Rho|ape|rho|Rfr|rfr|ord|REG|ang|reg|orv|And|and|AMP|Rcy|amp|Afr|ycy|Ycy|yen|yfr|Yfr|rcy|par|pcy|Pcy|pfr|Pfr|phi|Phi|afr|Acy|acy|zcy|Zcy|piv|acE|acd|zfr|Zfr|pre|prE|psi|Psi|qfr|Qfr|zwj|Or|ge|Gg|gt|gg|el|oS|lt|Lt|LT|Re|lg|gl|eg|ne|Im|it|le|DD|wp|wr|nu|Nu|dd|lE|Sc|sc|pi|Pi|ee|af|ll|Ll|rx|gE|xi|pm|Xi|ic|pr|Pr|in|ni|mp|mu|ac|Mu|or|ap|Gt|GT|ii);|&(Aacute|Agrave|Atilde|Ccedil|Eacute|Egrave|Iacute|Igrave|Ntilde|Oacute|Ograve|Oslash|Otilde|Uacute|Ugrave|Yacute|aacute|agrave|atilde|brvbar|ccedil|curren|divide|eacute|egrave|frac12|frac14|frac34|iacute|igrave|iquest|middot|ntilde|oacute|ograve|oslash|otilde|plusmn|uacute|ugrave|yacute|AElig|Acirc|Aring|Ecirc|Icirc|Ocirc|THORN|Ucirc|acirc|acute|aelig|aring|cedil|ecirc|icirc|iexcl|laquo|micro|ocirc|pound|raquo|szlig|thorn|times|ucirc|Auml|COPY|Euml|Iuml|Ouml|QUOT|Uuml|auml|cent|copy|euml|iuml|macr|nbsp|ordf|ordm|ouml|para|quot|sect|sup1|sup2|sup3|uuml|yuml|AMP|ETH|REG|amp|deg|eth|not|reg|shy|uml|yen|GT|LT|gt|lt)(?!;)([=a-zA-Z0-9]?)|&#([0-9]+)(;?)|&#[xX]([a-fA-F0-9]+)(;?)|&([0-9a-zA-Z]+)/g; + var decodeMap = { + 'aacute': 'á', + 'Aacute': 'Á', + 'abreve': 'ă', + 'Abreve': 'Ă', + 'ac': '\u223E', + 'acd': '\u223F', + 'acE': '\u223E̳', + 'acirc': 'â', + 'Acirc': 'Â', + 'acute': '\xB4', + 'acy': 'а', + 'Acy': 'А', + 'aelig': 'æ', + 'AElig': 'Æ', + 'af': '\u2061', + 'afr': '\uD835\uDD1E', + 'Afr': '\uD835\uDD04', + 'agrave': 'à', + 'Agrave': 'À', + 'alefsym': 'ℵ', + 'aleph': 'ℵ', + 'alpha': 'α', + 'Alpha': 'Α', + 'amacr': 'ā', + 'Amacr': 'Ā', + 'amalg': '\u2A3F', + 'amp': '&', + 'AMP': '&', + 'and': '\u2227', + 'And': '\u2A53', + 'andand': '\u2A55', + 'andd': '\u2A5C', + 'andslope': '\u2A58', + 'andv': '\u2A5A', + 'ang': '\u2220', + 'ange': '\u29A4', + 'angle': '\u2220', + 'angmsd': '\u2221', + 'angmsdaa': '\u29A8', + 'angmsdab': '\u29A9', + 'angmsdac': '\u29AA', + 'angmsdad': '\u29AB', + 'angmsdae': '\u29AC', + 'angmsdaf': '\u29AD', + 'angmsdag': '\u29AE', + 'angmsdah': '\u29AF', + 'angrt': '\u221F', + 'angrtvb': '\u22BE', + 'angrtvbd': '\u299D', + 'angsph': '\u2222', + 'angst': 'Å', + 'angzarr': '\u237C', + 'aogon': 'ą', + 'Aogon': 'Ą', + 'aopf': '\uD835\uDD52', + 'Aopf': '\uD835\uDD38', + 'ap': '\u2248', + 'apacir': '\u2A6F', + 'ape': '\u224A', + 'apE': '\u2A70', + 'apid': '\u224B', + 'apos': '\'', + 'ApplyFunction': '\u2061', + 'approx': '\u2248', + 'approxeq': '\u224A', + 'aring': 'å', + 'Aring': 'Å', + 'ascr': '\uD835\uDCB6', + 'Ascr': '\uD835\uDC9C', + 'Assign': '\u2254', + 'ast': '*', + 'asymp': '\u2248', + 'asympeq': '\u224D', + 'atilde': 'ã', + 'Atilde': 'Ã', + 'auml': 'ä', + 'Auml': 'Ä', + 'awconint': '\u2233', + 'awint': '\u2A11', + 'backcong': '\u224C', + 'backepsilon': '\u03F6', + 'backprime': '\u2035', + 'backsim': '\u223D', + 'backsimeq': '\u22CD', + 'Backslash': '\u2216', + 'Barv': '\u2AE7', + 'barvee': '\u22BD', + 'barwed': '\u2305', + 'Barwed': '\u2306', + 'barwedge': '\u2305', + 'bbrk': '\u23B5', + 'bbrktbrk': '\u23B6', + 'bcong': '\u224C', + 'bcy': 'б', + 'Bcy': 'Б', + 'bdquo': '\u201E', + 'becaus': '\u2235', + 'because': '\u2235', + 'Because': '\u2235', + 'bemptyv': '\u29B0', + 'bepsi': '\u03F6', + 'bernou': 'ℬ', + 'Bernoullis': 'ℬ', + 'beta': 'β', + 'Beta': 'Β', + 'beth': 'ℶ', + 'between': '\u226C', + 'bfr': '\uD835\uDD1F', + 'Bfr': '\uD835\uDD05', + 'bigcap': '\u22C2', + 'bigcirc': '\u25EF', + 'bigcup': '\u22C3', + 'bigodot': '\u2A00', + 'bigoplus': '\u2A01', + 'bigotimes': '\u2A02', + 'bigsqcup': '\u2A06', + 'bigstar': '\u2605', + 'bigtriangledown': '\u25BD', + 'bigtriangleup': '\u25B3', + 'biguplus': '\u2A04', + 'bigvee': '\u22C1', + 'bigwedge': '\u22C0', + 'bkarow': '\u290D', + 'blacklozenge': '\u29EB', + 'blacksquare': '\u25AA', + 'blacktriangle': '\u25B4', + 'blacktriangledown': '\u25BE', + 'blacktriangleleft': '\u25C2', + 'blacktriangleright': '\u25B8', + 'blank': '\u2423', + 'blk12': '\u2592', + 'blk14': '\u2591', + 'blk34': '\u2593', + 'block': '\u2588', + 'bne': '=⃥', + 'bnequiv': '\u2261⃥', + 'bnot': '\u2310', + 'bNot': '\u2AED', + 'bopf': '\uD835\uDD53', + 'Bopf': '\uD835\uDD39', + 'bot': '\u22A5', + 'bottom': '\u22A5', + 'bowtie': '\u22C8', + 'boxbox': '\u29C9', + 'boxdl': '\u2510', + 'boxdL': '\u2555', + 'boxDl': '\u2556', + 'boxDL': '\u2557', + 'boxdr': '\u250C', + 'boxdR': '\u2552', + 'boxDr': '\u2553', + 'boxDR': '\u2554', + 'boxh': '\u2500', + 'boxH': '\u2550', + 'boxhd': '\u252C', + 'boxhD': '\u2565', + 'boxHd': '\u2564', + 'boxHD': '\u2566', + 'boxhu': '\u2534', + 'boxhU': '\u2568', + 'boxHu': '\u2567', + 'boxHU': '\u2569', + 'boxminus': '\u229F', + 'boxplus': '\u229E', + 'boxtimes': '\u22A0', + 'boxul': '\u2518', + 'boxuL': '\u255B', + 'boxUl': '\u255C', + 'boxUL': '\u255D', + 'boxur': '\u2514', + 'boxuR': '\u2558', + 'boxUr': '\u2559', + 'boxUR': '\u255A', + 'boxv': '\u2502', + 'boxV': '\u2551', + 'boxvh': '\u253C', + 'boxvH': '\u256A', + 'boxVh': '\u256B', + 'boxVH': '\u256C', + 'boxvl': '\u2524', + 'boxvL': '\u2561', + 'boxVl': '\u2562', + 'boxVL': '\u2563', + 'boxvr': '\u251C', + 'boxvR': '\u255E', + 'boxVr': '\u255F', + 'boxVR': '\u2560', + 'bprime': '\u2035', + 'breve': '\u02D8', + 'Breve': '\u02D8', + 'brvbar': '\xA6', + 'bscr': '\uD835\uDCB7', + 'Bscr': 'ℬ', + 'bsemi': '\u204F', + 'bsim': '\u223D', + 'bsime': '\u22CD', + 'bsol': '\\', + 'bsolb': '\u29C5', + 'bsolhsub': '\u27C8', + 'bull': '\u2022', + 'bullet': '\u2022', + 'bump': '\u224E', + 'bumpe': '\u224F', + 'bumpE': '\u2AAE', + 'bumpeq': '\u224F', + 'Bumpeq': '\u224E', + 'cacute': 'ć', + 'Cacute': 'Ć', + 'cap': '\u2229', + 'Cap': '\u22D2', + 'capand': '\u2A44', + 'capbrcup': '\u2A49', + 'capcap': '\u2A4B', + 'capcup': '\u2A47', + 'capdot': '\u2A40', + 'CapitalDifferentialD': 'ⅅ', + 'caps': '\u2229︀', + 'caret': '\u2041', + 'caron': 'ˇ', + 'Cayleys': 'ℭ', + 'ccaps': '\u2A4D', + 'ccaron': 'č', + 'Ccaron': 'Č', + 'ccedil': 'ç', + 'Ccedil': 'Ç', + 'ccirc': 'ĉ', + 'Ccirc': 'Ĉ', + 'Cconint': '\u2230', + 'ccups': '\u2A4C', + 'ccupssm': '\u2A50', + 'cdot': 'ċ', + 'Cdot': 'Ċ', + 'cedil': '\xB8', + 'Cedilla': '\xB8', + 'cemptyv': '\u29B2', + 'cent': '\xA2', + 'centerdot': '\xB7', + 'CenterDot': '\xB7', + 'cfr': '\uD835\uDD20', + 'Cfr': 'ℭ', + 'chcy': 'ч', + 'CHcy': 'Ч', + 'check': '\u2713', + 'checkmark': '\u2713', + 'chi': 'χ', + 'Chi': 'Χ', + 'cir': '\u25CB', + 'circ': 'ˆ', + 'circeq': '\u2257', + 'circlearrowleft': '\u21BA', + 'circlearrowright': '\u21BB', + 'circledast': '\u229B', + 'circledcirc': '\u229A', + 'circleddash': '\u229D', + 'CircleDot': '\u2299', + 'circledR': '\xAE', + 'circledS': '\u24C8', + 'CircleMinus': '\u2296', + 'CirclePlus': '\u2295', + 'CircleTimes': '\u2297', + 'cire': '\u2257', + 'cirE': '\u29C3', + 'cirfnint': '\u2A10', + 'cirmid': '\u2AEF', + 'cirscir': '\u29C2', + 'ClockwiseContourIntegral': '\u2232', + 'CloseCurlyDoubleQuote': '\u201D', + 'CloseCurlyQuote': '\u2019', + 'clubs': '\u2663', + 'clubsuit': '\u2663', + 'colon': ':', + 'Colon': '\u2237', + 'colone': '\u2254', + 'Colone': '\u2A74', + 'coloneq': '\u2254', + 'comma': ',', + 'commat': '@', + 'comp': '\u2201', + 'compfn': '\u2218', + 'complement': '\u2201', + 'complexes': 'ℂ', + 'cong': '\u2245', + 'congdot': '\u2A6D', + 'Congruent': '\u2261', + 'conint': '\u222E', + 'Conint': '\u222F', + 'ContourIntegral': '\u222E', + 'copf': '\uD835\uDD54', + 'Copf': 'ℂ', + 'coprod': '\u2210', + 'Coproduct': '\u2210', + 'copy': '\xA9', + 'COPY': '\xA9', + 'copysr': '\u2117', + 'CounterClockwiseContourIntegral': '\u2233', + 'crarr': '\u21B5', + 'cross': '\u2717', + 'Cross': '\u2A2F', + 'cscr': '\uD835\uDCB8', + 'Cscr': '\uD835\uDC9E', + 'csub': '\u2ACF', + 'csube': '\u2AD1', + 'csup': '\u2AD0', + 'csupe': '\u2AD2', + 'ctdot': '\u22EF', + 'cudarrl': '\u2938', + 'cudarrr': '\u2935', + 'cuepr': '\u22DE', + 'cuesc': '\u22DF', + 'cularr': '\u21B6', + 'cularrp': '\u293D', + 'cup': '\u222A', + 'Cup': '\u22D3', + 'cupbrcap': '\u2A48', + 'cupcap': '\u2A46', + 'CupCap': '\u224D', + 'cupcup': '\u2A4A', + 'cupdot': '\u228D', + 'cupor': '\u2A45', + 'cups': '\u222A︀', + 'curarr': '\u21B7', + 'curarrm': '\u293C', + 'curlyeqprec': '\u22DE', + 'curlyeqsucc': '\u22DF', + 'curlyvee': '\u22CE', + 'curlywedge': '\u22CF', + 'curren': '\xA4', + 'curvearrowleft': '\u21B6', + 'curvearrowright': '\u21B7', + 'cuvee': '\u22CE', + 'cuwed': '\u22CF', + 'cwconint': '\u2232', + 'cwint': '\u2231', + 'cylcty': '\u232D', + 'dagger': '\u2020', + 'Dagger': '\u2021', + 'daleth': 'ℸ', + 'darr': '\u2193', + 'dArr': '\u21D3', + 'Darr': '\u21A1', + 'dash': '\u2010', + 'dashv': '\u22A3', + 'Dashv': '\u2AE4', + 'dbkarow': '\u290F', + 'dblac': '\u02DD', + 'dcaron': 'ď', + 'Dcaron': 'Ď', + 'dcy': 'д', + 'Dcy': 'Д', + 'dd': 'ⅆ', + 'DD': 'ⅅ', + 'ddagger': '\u2021', + 'ddarr': '\u21CA', + 'DDotrahd': '\u2911', + 'ddotseq': '\u2A77', + 'deg': '\xB0', + 'Del': '\u2207', + 'delta': 'δ', + 'Delta': 'Δ', + 'demptyv': '\u29B1', + 'dfisht': '\u297F', + 'dfr': '\uD835\uDD21', + 'Dfr': '\uD835\uDD07', + 'dHar': '\u2965', + 'dharl': '\u21C3', + 'dharr': '\u21C2', + 'DiacriticalAcute': '\xB4', + 'DiacriticalDot': '\u02D9', + 'DiacriticalDoubleAcute': '\u02DD', + 'DiacriticalGrave': '`', + 'DiacriticalTilde': '\u02DC', + 'diam': '\u22C4', + 'diamond': '\u22C4', + 'Diamond': '\u22C4', + 'diamondsuit': '\u2666', + 'diams': '\u2666', + 'die': '\xA8', + 'DifferentialD': 'ⅆ', + 'digamma': 'ϝ', + 'disin': '\u22F2', + 'div': '\xF7', + 'divide': '\xF7', + 'divideontimes': '\u22C7', + 'divonx': '\u22C7', + 'djcy': 'ђ', + 'DJcy': 'Ђ', + 'dlcorn': '\u231E', + 'dlcrop': '\u230D', + 'dollar': '$', + 'dopf': '\uD835\uDD55', + 'Dopf': '\uD835\uDD3B', + 'dot': '\u02D9', + 'Dot': '\xA8', + 'DotDot': '⃜', + 'doteq': '\u2250', + 'doteqdot': '\u2251', + 'DotEqual': '\u2250', + 'dotminus': '\u2238', + 'dotplus': '\u2214', + 'dotsquare': '\u22A1', + 'doublebarwedge': '\u2306', + 'DoubleContourIntegral': '\u222F', + 'DoubleDot': '\xA8', + 'DoubleDownArrow': '\u21D3', + 'DoubleLeftArrow': '\u21D0', + 'DoubleLeftRightArrow': '\u21D4', + 'DoubleLeftTee': '\u2AE4', + 'DoubleLongLeftArrow': '\u27F8', + 'DoubleLongLeftRightArrow': '\u27FA', + 'DoubleLongRightArrow': '\u27F9', + 'DoubleRightArrow': '\u21D2', + 'DoubleRightTee': '\u22A8', + 'DoubleUpArrow': '\u21D1', + 'DoubleUpDownArrow': '\u21D5', + 'DoubleVerticalBar': '\u2225', + 'downarrow': '\u2193', + 'Downarrow': '\u21D3', + 'DownArrow': '\u2193', + 'DownArrowBar': '\u2913', + 'DownArrowUpArrow': '\u21F5', + 'DownBreve': '̑', + 'downdownarrows': '\u21CA', + 'downharpoonleft': '\u21C3', + 'downharpoonright': '\u21C2', + 'DownLeftRightVector': '\u2950', + 'DownLeftTeeVector': '\u295E', + 'DownLeftVector': '\u21BD', + 'DownLeftVectorBar': '\u2956', + 'DownRightTeeVector': '\u295F', + 'DownRightVector': '\u21C1', + 'DownRightVectorBar': '\u2957', + 'DownTee': '\u22A4', + 'DownTeeArrow': '\u21A7', + 'drbkarow': '\u2910', + 'drcorn': '\u231F', + 'drcrop': '\u230C', + 'dscr': '\uD835\uDCB9', + 'Dscr': '\uD835\uDC9F', + 'dscy': 'ѕ', + 'DScy': 'Ѕ', + 'dsol': '\u29F6', + 'dstrok': 'đ', + 'Dstrok': 'Đ', + 'dtdot': '\u22F1', + 'dtri': '\u25BF', + 'dtrif': '\u25BE', + 'duarr': '\u21F5', + 'duhar': '\u296F', + 'dwangle': '\u29A6', + 'dzcy': 'џ', + 'DZcy': 'Џ', + 'dzigrarr': '\u27FF', + 'eacute': 'é', + 'Eacute': 'É', + 'easter': '\u2A6E', + 'ecaron': 'ě', + 'Ecaron': 'Ě', + 'ecir': '\u2256', + 'ecirc': 'ê', + 'Ecirc': 'Ê', + 'ecolon': '\u2255', + 'ecy': 'э', + 'Ecy': 'Э', + 'eDDot': '\u2A77', + 'edot': 'ė', + 'eDot': '\u2251', + 'Edot': 'Ė', + 'ee': 'ⅇ', + 'efDot': '\u2252', + 'efr': '\uD835\uDD22', + 'Efr': '\uD835\uDD08', + 'eg': '\u2A9A', + 'egrave': 'è', + 'Egrave': 'È', + 'egs': '\u2A96', + 'egsdot': '\u2A98', + 'el': '\u2A99', + 'Element': '\u2208', + 'elinters': '\u23E7', + 'ell': 'ℓ', + 'els': '\u2A95', + 'elsdot': '\u2A97', + 'emacr': 'ē', + 'Emacr': 'Ē', + 'empty': '\u2205', + 'emptyset': '\u2205', + 'EmptySmallSquare': '\u25FB', + 'emptyv': '\u2205', + 'EmptyVerySmallSquare': '\u25AB', + 'emsp': '\u2003', + 'emsp13': '\u2004', + 'emsp14': '\u2005', + 'eng': 'ŋ', + 'ENG': 'Ŋ', + 'ensp': '\u2002', + 'eogon': 'ę', + 'Eogon': 'Ę', + 'eopf': '\uD835\uDD56', + 'Eopf': '\uD835\uDD3C', + 'epar': '\u22D5', + 'eparsl': '\u29E3', + 'eplus': '\u2A71', + 'epsi': 'ε', + 'epsilon': 'ε', + 'Epsilon': 'Ε', + 'epsiv': 'ϵ', + 'eqcirc': '\u2256', + 'eqcolon': '\u2255', + 'eqsim': '\u2242', + 'eqslantgtr': '\u2A96', + 'eqslantless': '\u2A95', + 'Equal': '\u2A75', + 'equals': '=', + 'EqualTilde': '\u2242', + 'equest': '\u225F', + 'Equilibrium': '\u21CC', + 'equiv': '\u2261', + 'equivDD': '\u2A78', + 'eqvparsl': '\u29E5', + 'erarr': '\u2971', + 'erDot': '\u2253', + 'escr': 'ℯ', + 'Escr': 'ℰ', + 'esdot': '\u2250', + 'esim': '\u2242', + 'Esim': '\u2A73', + 'eta': 'η', + 'Eta': 'Η', + 'eth': 'ð', + 'ETH': 'Ð', + 'euml': 'ë', + 'Euml': 'Ë', + 'euro': '\u20AC', + 'excl': '!', + 'exist': '\u2203', + 'Exists': '\u2203', + 'expectation': 'ℰ', + 'exponentiale': 'ⅇ', + 'ExponentialE': 'ⅇ', + 'fallingdotseq': '\u2252', + 'fcy': 'ф', + 'Fcy': 'Ф', + 'female': '\u2640', + 'ffilig': 'ffi', + 'fflig': 'ff', + 'ffllig': 'ffl', + 'ffr': '\uD835\uDD23', + 'Ffr': '\uD835\uDD09', + 'filig': 'fi', + 'FilledSmallSquare': '\u25FC', + 'FilledVerySmallSquare': '\u25AA', + 'fjlig': 'fj', + 'flat': '\u266D', + 'fllig': 'fl', + 'fltns': '\u25B1', + 'fnof': 'ƒ', + 'fopf': '\uD835\uDD57', + 'Fopf': '\uD835\uDD3D', + 'forall': '\u2200', + 'ForAll': '\u2200', + 'fork': '\u22D4', + 'forkv': '\u2AD9', + 'Fouriertrf': 'ℱ', + 'fpartint': '\u2A0D', + 'frac12': '\xBD', + 'frac13': '\u2153', + 'frac14': '\xBC', + 'frac15': '\u2155', + 'frac16': '\u2159', + 'frac18': '\u215B', + 'frac23': '\u2154', + 'frac25': '\u2156', + 'frac34': '\xBE', + 'frac35': '\u2157', + 'frac38': '\u215C', + 'frac45': '\u2158', + 'frac56': '\u215A', + 'frac58': '\u215D', + 'frac78': '\u215E', + 'frasl': '\u2044', + 'frown': '\u2322', + 'fscr': '\uD835\uDCBB', + 'Fscr': 'ℱ', + 'gacute': 'ǵ', + 'gamma': 'γ', + 'Gamma': 'Γ', + 'gammad': 'ϝ', + 'Gammad': 'Ϝ', + 'gap': '\u2A86', + 'gbreve': 'ğ', + 'Gbreve': 'Ğ', + 'Gcedil': 'Ģ', + 'gcirc': 'ĝ', + 'Gcirc': 'Ĝ', + 'gcy': 'г', + 'Gcy': 'Г', + 'gdot': 'ġ', + 'Gdot': 'Ġ', + 'ge': '\u2265', + 'gE': '\u2267', + 'gel': '\u22DB', + 'gEl': '\u2A8C', + 'geq': '\u2265', + 'geqq': '\u2267', + 'geqslant': '\u2A7E', + 'ges': '\u2A7E', + 'gescc': '\u2AA9', + 'gesdot': '\u2A80', + 'gesdoto': '\u2A82', + 'gesdotol': '\u2A84', + 'gesl': '\u22DB︀', + 'gesles': '\u2A94', + 'gfr': '\uD835\uDD24', + 'Gfr': '\uD835\uDD0A', + 'gg': '\u226B', + 'Gg': '\u22D9', + 'ggg': '\u22D9', + 'gimel': 'ℷ', + 'gjcy': 'ѓ', + 'GJcy': 'Ѓ', + 'gl': '\u2277', + 'gla': '\u2AA5', + 'glE': '\u2A92', + 'glj': '\u2AA4', + 'gnap': '\u2A8A', + 'gnapprox': '\u2A8A', + 'gne': '\u2A88', + 'gnE': '\u2269', + 'gneq': '\u2A88', + 'gneqq': '\u2269', + 'gnsim': '\u22E7', + 'gopf': '\uD835\uDD58', + 'Gopf': '\uD835\uDD3E', + 'grave': '`', + 'GreaterEqual': '\u2265', + 'GreaterEqualLess': '\u22DB', + 'GreaterFullEqual': '\u2267', + 'GreaterGreater': '\u2AA2', + 'GreaterLess': '\u2277', + 'GreaterSlantEqual': '\u2A7E', + 'GreaterTilde': '\u2273', + 'gscr': 'ℊ', + 'Gscr': '\uD835\uDCA2', + 'gsim': '\u2273', + 'gsime': '\u2A8E', + 'gsiml': '\u2A90', + 'gt': '>', + 'Gt': '\u226B', + 'GT': '>', + 'gtcc': '\u2AA7', + 'gtcir': '\u2A7A', + 'gtdot': '\u22D7', + 'gtlPar': '\u2995', + 'gtquest': '\u2A7C', + 'gtrapprox': '\u2A86', + 'gtrarr': '\u2978', + 'gtrdot': '\u22D7', + 'gtreqless': '\u22DB', + 'gtreqqless': '\u2A8C', + 'gtrless': '\u2277', + 'gtrsim': '\u2273', + 'gvertneqq': '\u2269︀', + 'gvnE': '\u2269︀', + 'Hacek': 'ˇ', + 'hairsp': '\u200A', + 'half': '\xBD', + 'hamilt': 'ℋ', + 'hardcy': 'ъ', + 'HARDcy': 'Ъ', + 'harr': '\u2194', + 'hArr': '\u21D4', + 'harrcir': '\u2948', + 'harrw': '\u21AD', + 'Hat': '^', + 'hbar': 'ℏ', + 'hcirc': 'ĥ', + 'Hcirc': 'Ĥ', + 'hearts': '\u2665', + 'heartsuit': '\u2665', + 'hellip': '\u2026', + 'hercon': '\u22B9', + 'hfr': '\uD835\uDD25', + 'Hfr': 'ℌ', + 'HilbertSpace': 'ℋ', + 'hksearow': '\u2925', + 'hkswarow': '\u2926', + 'hoarr': '\u21FF', + 'homtht': '\u223B', + 'hookleftarrow': '\u21A9', + 'hookrightarrow': '\u21AA', + 'hopf': '\uD835\uDD59', + 'Hopf': 'ℍ', + 'horbar': '\u2015', + 'HorizontalLine': '\u2500', + 'hscr': '\uD835\uDCBD', + 'Hscr': 'ℋ', + 'hslash': 'ℏ', + 'hstrok': 'ħ', + 'Hstrok': 'Ħ', + 'HumpDownHump': '\u224E', + 'HumpEqual': '\u224F', + 'hybull': '\u2043', + 'hyphen': '\u2010', + 'iacute': 'í', + 'Iacute': 'Í', + 'ic': '\u2063', + 'icirc': 'î', + 'Icirc': 'Î', + 'icy': 'и', + 'Icy': 'И', + 'Idot': 'İ', + 'iecy': 'е', + 'IEcy': 'Е', + 'iexcl': '\xA1', + 'iff': '\u21D4', + 'ifr': '\uD835\uDD26', + 'Ifr': 'ℑ', + 'igrave': 'ì', + 'Igrave': 'Ì', + 'ii': 'ⅈ', + 'iiiint': '\u2A0C', + 'iiint': '\u222D', + 'iinfin': '\u29DC', + 'iiota': '\u2129', + 'ijlig': 'ij', + 'IJlig': 'IJ', + 'Im': 'ℑ', + 'imacr': 'ī', + 'Imacr': 'Ī', + 'image': 'ℑ', + 'ImaginaryI': 'ⅈ', + 'imagline': 'ℐ', + 'imagpart': 'ℑ', + 'imath': 'ı', + 'imof': '\u22B7', + 'imped': 'Ƶ', + 'Implies': '\u21D2', + 'in': '\u2208', + 'incare': '\u2105', + 'infin': '\u221E', + 'infintie': '\u29DD', + 'inodot': 'ı', + 'int': '\u222B', + 'Int': '\u222C', + 'intcal': '\u22BA', + 'integers': 'ℤ', + 'Integral': '\u222B', + 'intercal': '\u22BA', + 'Intersection': '\u22C2', + 'intlarhk': '\u2A17', + 'intprod': '\u2A3C', + 'InvisibleComma': '\u2063', + 'InvisibleTimes': '\u2062', + 'iocy': 'ё', + 'IOcy': 'Ё', + 'iogon': 'į', + 'Iogon': 'Į', + 'iopf': '\uD835\uDD5A', + 'Iopf': '\uD835\uDD40', + 'iota': 'ι', + 'Iota': 'Ι', + 'iprod': '\u2A3C', + 'iquest': '\xBF', + 'iscr': '\uD835\uDCBE', + 'Iscr': 'ℐ', + 'isin': '\u2208', + 'isindot': '\u22F5', + 'isinE': '\u22F9', + 'isins': '\u22F4', + 'isinsv': '\u22F3', + 'isinv': '\u2208', + 'it': '\u2062', + 'itilde': 'ĩ', + 'Itilde': 'Ĩ', + 'iukcy': 'і', + 'Iukcy': 'І', + 'iuml': 'ï', + 'Iuml': 'Ï', + 'jcirc': 'ĵ', + 'Jcirc': 'Ĵ', + 'jcy': 'й', + 'Jcy': 'Й', + 'jfr': '\uD835\uDD27', + 'Jfr': '\uD835\uDD0D', + 'jmath': 'ȷ', + 'jopf': '\uD835\uDD5B', + 'Jopf': '\uD835\uDD41', + 'jscr': '\uD835\uDCBF', + 'Jscr': '\uD835\uDCA5', + 'jsercy': 'ј', + 'Jsercy': 'Ј', + 'jukcy': 'є', + 'Jukcy': 'Є', + 'kappa': 'κ', + 'Kappa': 'Κ', + 'kappav': 'ϰ', + 'kcedil': 'ķ', + 'Kcedil': 'Ķ', + 'kcy': 'к', + 'Kcy': 'К', + 'kfr': '\uD835\uDD28', + 'Kfr': '\uD835\uDD0E', + 'kgreen': 'ĸ', + 'khcy': 'х', + 'KHcy': 'Х', + 'kjcy': 'ќ', + 'KJcy': 'Ќ', + 'kopf': '\uD835\uDD5C', + 'Kopf': '\uD835\uDD42', + 'kscr': '\uD835\uDCC0', + 'Kscr': '\uD835\uDCA6', + 'lAarr': '\u21DA', + 'lacute': 'ĺ', + 'Lacute': 'Ĺ', + 'laemptyv': '\u29B4', + 'lagran': 'ℒ', + 'lambda': 'λ', + 'Lambda': 'Λ', + 'lang': '\u27E8', + 'Lang': '\u27EA', + 'langd': '\u2991', + 'langle': '\u27E8', + 'lap': '\u2A85', + 'Laplacetrf': 'ℒ', + 'laquo': '\xAB', + 'larr': '\u2190', + 'lArr': '\u21D0', + 'Larr': '\u219E', + 'larrb': '\u21E4', + 'larrbfs': '\u291F', + 'larrfs': '\u291D', + 'larrhk': '\u21A9', + 'larrlp': '\u21AB', + 'larrpl': '\u2939', + 'larrsim': '\u2973', + 'larrtl': '\u21A2', + 'lat': '\u2AAB', + 'latail': '\u2919', + 'lAtail': '\u291B', + 'late': '\u2AAD', + 'lates': '\u2AAD︀', + 'lbarr': '\u290C', + 'lBarr': '\u290E', + 'lbbrk': '\u2772', + 'lbrace': '{', + 'lbrack': '[', + 'lbrke': '\u298B', + 'lbrksld': '\u298F', + 'lbrkslu': '\u298D', + 'lcaron': 'ľ', + 'Lcaron': 'Ľ', + 'lcedil': 'ļ', + 'Lcedil': 'Ļ', + 'lceil': '\u2308', + 'lcub': '{', + 'lcy': 'л', + 'Lcy': 'Л', + 'ldca': '\u2936', + 'ldquo': '\u201C', + 'ldquor': '\u201E', + 'ldrdhar': '\u2967', + 'ldrushar': '\u294B', + 'ldsh': '\u21B2', + 'le': '\u2264', + 'lE': '\u2266', + 'LeftAngleBracket': '\u27E8', + 'leftarrow': '\u2190', + 'Leftarrow': '\u21D0', + 'LeftArrow': '\u2190', + 'LeftArrowBar': '\u21E4', + 'LeftArrowRightArrow': '\u21C6', + 'leftarrowtail': '\u21A2', + 'LeftCeiling': '\u2308', + 'LeftDoubleBracket': '\u27E6', + 'LeftDownTeeVector': '\u2961', + 'LeftDownVector': '\u21C3', + 'LeftDownVectorBar': '\u2959', + 'LeftFloor': '\u230A', + 'leftharpoondown': '\u21BD', + 'leftharpoonup': '\u21BC', + 'leftleftarrows': '\u21C7', + 'leftrightarrow': '\u2194', + 'Leftrightarrow': '\u21D4', + 'LeftRightArrow': '\u2194', + 'leftrightarrows': '\u21C6', + 'leftrightharpoons': '\u21CB', + 'leftrightsquigarrow': '\u21AD', + 'LeftRightVector': '\u294E', + 'LeftTee': '\u22A3', + 'LeftTeeArrow': '\u21A4', + 'LeftTeeVector': '\u295A', + 'leftthreetimes': '\u22CB', + 'LeftTriangle': '\u22B2', + 'LeftTriangleBar': '\u29CF', + 'LeftTriangleEqual': '\u22B4', + 'LeftUpDownVector': '\u2951', + 'LeftUpTeeVector': '\u2960', + 'LeftUpVector': '\u21BF', + 'LeftUpVectorBar': '\u2958', + 'LeftVector': '\u21BC', + 'LeftVectorBar': '\u2952', + 'leg': '\u22DA', + 'lEg': '\u2A8B', + 'leq': '\u2264', + 'leqq': '\u2266', + 'leqslant': '\u2A7D', + 'les': '\u2A7D', + 'lescc': '\u2AA8', + 'lesdot': '\u2A7F', + 'lesdoto': '\u2A81', + 'lesdotor': '\u2A83', + 'lesg': '\u22DA︀', + 'lesges': '\u2A93', + 'lessapprox': '\u2A85', + 'lessdot': '\u22D6', + 'lesseqgtr': '\u22DA', + 'lesseqqgtr': '\u2A8B', + 'LessEqualGreater': '\u22DA', + 'LessFullEqual': '\u2266', + 'LessGreater': '\u2276', + 'lessgtr': '\u2276', + 'LessLess': '\u2AA1', + 'lesssim': '\u2272', + 'LessSlantEqual': '\u2A7D', + 'LessTilde': '\u2272', + 'lfisht': '\u297C', + 'lfloor': '\u230A', + 'lfr': '\uD835\uDD29', + 'Lfr': '\uD835\uDD0F', + 'lg': '\u2276', + 'lgE': '\u2A91', + 'lHar': '\u2962', + 'lhard': '\u21BD', + 'lharu': '\u21BC', + 'lharul': '\u296A', + 'lhblk': '\u2584', + 'ljcy': 'љ', + 'LJcy': 'Љ', + 'll': '\u226A', + 'Ll': '\u22D8', + 'llarr': '\u21C7', + 'llcorner': '\u231E', + 'Lleftarrow': '\u21DA', + 'llhard': '\u296B', + 'lltri': '\u25FA', + 'lmidot': 'ŀ', + 'Lmidot': 'Ŀ', + 'lmoust': '\u23B0', + 'lmoustache': '\u23B0', + 'lnap': '\u2A89', + 'lnapprox': '\u2A89', + 'lne': '\u2A87', + 'lnE': '\u2268', + 'lneq': '\u2A87', + 'lneqq': '\u2268', + 'lnsim': '\u22E6', + 'loang': '\u27EC', + 'loarr': '\u21FD', + 'lobrk': '\u27E6', + 'longleftarrow': '\u27F5', + 'Longleftarrow': '\u27F8', + 'LongLeftArrow': '\u27F5', + 'longleftrightarrow': '\u27F7', + 'Longleftrightarrow': '\u27FA', + 'LongLeftRightArrow': '\u27F7', + 'longmapsto': '\u27FC', + 'longrightarrow': '\u27F6', + 'Longrightarrow': '\u27F9', + 'LongRightArrow': '\u27F6', + 'looparrowleft': '\u21AB', + 'looparrowright': '\u21AC', + 'lopar': '\u2985', + 'lopf': '\uD835\uDD5D', + 'Lopf': '\uD835\uDD43', + 'loplus': '\u2A2D', + 'lotimes': '\u2A34', + 'lowast': '\u2217', + 'lowbar': '_', + 'LowerLeftArrow': '\u2199', + 'LowerRightArrow': '\u2198', + 'loz': '\u25CA', + 'lozenge': '\u25CA', + 'lozf': '\u29EB', + 'lpar': '(', + 'lparlt': '\u2993', + 'lrarr': '\u21C6', + 'lrcorner': '\u231F', + 'lrhar': '\u21CB', + 'lrhard': '\u296D', + 'lrm': '\u200E', + 'lrtri': '\u22BF', + 'lsaquo': '\u2039', + 'lscr': '\uD835\uDCC1', + 'Lscr': 'ℒ', + 'lsh': '\u21B0', + 'Lsh': '\u21B0', + 'lsim': '\u2272', + 'lsime': '\u2A8D', + 'lsimg': '\u2A8F', + 'lsqb': '[', + 'lsquo': '\u2018', + 'lsquor': '\u201A', + 'lstrok': 'ł', + 'Lstrok': 'Ł', + 'lt': '<', + 'Lt': '\u226A', + 'LT': '<', + 'ltcc': '\u2AA6', + 'ltcir': '\u2A79', + 'ltdot': '\u22D6', + 'lthree': '\u22CB', + 'ltimes': '\u22C9', + 'ltlarr': '\u2976', + 'ltquest': '\u2A7B', + 'ltri': '\u25C3', + 'ltrie': '\u22B4', + 'ltrif': '\u25C2', + 'ltrPar': '\u2996', + 'lurdshar': '\u294A', + 'luruhar': '\u2966', + 'lvertneqq': '\u2268︀', + 'lvnE': '\u2268︀', + 'macr': '\xAF', + 'male': '\u2642', + 'malt': '\u2720', + 'maltese': '\u2720', + 'map': '\u21A6', + 'Map': '\u2905', + 'mapsto': '\u21A6', + 'mapstodown': '\u21A7', + 'mapstoleft': '\u21A4', + 'mapstoup': '\u21A5', + 'marker': '\u25AE', + 'mcomma': '\u2A29', + 'mcy': 'м', + 'Mcy': 'М', + 'mdash': '\u2014', + 'mDDot': '\u223A', + 'measuredangle': '\u2221', + 'MediumSpace': '\u205F', + 'Mellintrf': 'ℳ', + 'mfr': '\uD835\uDD2A', + 'Mfr': '\uD835\uDD10', + 'mho': '\u2127', + 'micro': 'µ', + 'mid': '\u2223', + 'midast': '*', + 'midcir': '\u2AF0', + 'middot': '\xB7', + 'minus': '\u2212', + 'minusb': '\u229F', + 'minusd': '\u2238', + 'minusdu': '\u2A2A', + 'MinusPlus': '\u2213', + 'mlcp': '\u2ADB', + 'mldr': '\u2026', + 'mnplus': '\u2213', + 'models': '\u22A7', + 'mopf': '\uD835\uDD5E', + 'Mopf': '\uD835\uDD44', + 'mp': '\u2213', + 'mscr': '\uD835\uDCC2', + 'Mscr': 'ℳ', + 'mstpos': '\u223E', + 'mu': 'μ', + 'Mu': 'Μ', + 'multimap': '\u22B8', + 'mumap': '\u22B8', + 'nabla': '\u2207', + 'nacute': 'ń', + 'Nacute': 'Ń', + 'nang': '\u2220⃒', + 'nap': '\u2249', + 'napE': '\u2A70̸', + 'napid': '\u224B̸', + 'napos': 'ʼn', + 'napprox': '\u2249', + 'natur': '\u266E', + 'natural': '\u266E', + 'naturals': 'ℕ', + 'nbsp': '\xA0', + 'nbump': '\u224E̸', + 'nbumpe': '\u224F̸', + 'ncap': '\u2A43', + 'ncaron': 'ň', + 'Ncaron': 'Ň', + 'ncedil': 'ņ', + 'Ncedil': 'Ņ', + 'ncong': '\u2247', + 'ncongdot': '\u2A6D̸', + 'ncup': '\u2A42', + 'ncy': 'н', + 'Ncy': 'Н', + 'ndash': '\u2013', + 'ne': '\u2260', + 'nearhk': '\u2924', + 'nearr': '\u2197', + 'neArr': '\u21D7', + 'nearrow': '\u2197', + 'nedot': '\u2250̸', + 'NegativeMediumSpace': '\u200B', + 'NegativeThickSpace': '\u200B', + 'NegativeThinSpace': '\u200B', + 'NegativeVeryThinSpace': '\u200B', + 'nequiv': '\u2262', + 'nesear': '\u2928', + 'nesim': '\u2242̸', + 'NestedGreaterGreater': '\u226B', + 'NestedLessLess': '\u226A', + 'NewLine': '\n', + 'nexist': '\u2204', + 'nexists': '\u2204', + 'nfr': '\uD835\uDD2B', + 'Nfr': '\uD835\uDD11', + 'nge': '\u2271', + 'ngE': '\u2267̸', + 'ngeq': '\u2271', + 'ngeqq': '\u2267̸', + 'ngeqslant': '\u2A7E̸', + 'nges': '\u2A7E̸', + 'nGg': '\u22D9̸', + 'ngsim': '\u2275', + 'ngt': '\u226F', + 'nGt': '\u226B⃒', + 'ngtr': '\u226F', + 'nGtv': '\u226B̸', + 'nharr': '\u21AE', + 'nhArr': '\u21CE', + 'nhpar': '\u2AF2', + 'ni': '\u220B', + 'nis': '\u22FC', + 'nisd': '\u22FA', + 'niv': '\u220B', + 'njcy': 'њ', + 'NJcy': 'Њ', + 'nlarr': '\u219A', + 'nlArr': '\u21CD', + 'nldr': '\u2025', + 'nle': '\u2270', + 'nlE': '\u2266̸', + 'nleftarrow': '\u219A', + 'nLeftarrow': '\u21CD', + 'nleftrightarrow': '\u21AE', + 'nLeftrightarrow': '\u21CE', + 'nleq': '\u2270', + 'nleqq': '\u2266̸', + 'nleqslant': '\u2A7D̸', + 'nles': '\u2A7D̸', + 'nless': '\u226E', + 'nLl': '\u22D8̸', + 'nlsim': '\u2274', + 'nlt': '\u226E', + 'nLt': '\u226A⃒', + 'nltri': '\u22EA', + 'nltrie': '\u22EC', + 'nLtv': '\u226A̸', + 'nmid': '\u2224', + 'NoBreak': '\u2060', + 'NonBreakingSpace': '\xA0', + 'nopf': '\uD835\uDD5F', + 'Nopf': 'ℕ', + 'not': '\xAC', + 'Not': '\u2AEC', + 'NotCongruent': '\u2262', + 'NotCupCap': '\u226D', + 'NotDoubleVerticalBar': '\u2226', + 'NotElement': '\u2209', + 'NotEqual': '\u2260', + 'NotEqualTilde': '\u2242̸', + 'NotExists': '\u2204', + 'NotGreater': '\u226F', + 'NotGreaterEqual': '\u2271', + 'NotGreaterFullEqual': '\u2267̸', + 'NotGreaterGreater': '\u226B̸', + 'NotGreaterLess': '\u2279', + 'NotGreaterSlantEqual': '\u2A7E̸', + 'NotGreaterTilde': '\u2275', + 'NotHumpDownHump': '\u224E̸', + 'NotHumpEqual': '\u224F̸', + 'notin': '\u2209', + 'notindot': '\u22F5̸', + 'notinE': '\u22F9̸', + 'notinva': '\u2209', + 'notinvb': '\u22F7', + 'notinvc': '\u22F6', + 'NotLeftTriangle': '\u22EA', + 'NotLeftTriangleBar': '\u29CF̸', + 'NotLeftTriangleEqual': '\u22EC', + 'NotLess': '\u226E', + 'NotLessEqual': '\u2270', + 'NotLessGreater': '\u2278', + 'NotLessLess': '\u226A̸', + 'NotLessSlantEqual': '\u2A7D̸', + 'NotLessTilde': '\u2274', + 'NotNestedGreaterGreater': '\u2AA2̸', + 'NotNestedLessLess': '\u2AA1̸', + 'notni': '\u220C', + 'notniva': '\u220C', + 'notnivb': '\u22FE', + 'notnivc': '\u22FD', + 'NotPrecedes': '\u2280', + 'NotPrecedesEqual': '\u2AAF̸', + 'NotPrecedesSlantEqual': '\u22E0', + 'NotReverseElement': '\u220C', + 'NotRightTriangle': '\u22EB', + 'NotRightTriangleBar': '\u29D0̸', + 'NotRightTriangleEqual': '\u22ED', + 'NotSquareSubset': '\u228F̸', + 'NotSquareSubsetEqual': '\u22E2', + 'NotSquareSuperset': '\u2290̸', + 'NotSquareSupersetEqual': '\u22E3', + 'NotSubset': '\u2282⃒', + 'NotSubsetEqual': '\u2288', + 'NotSucceeds': '\u2281', + 'NotSucceedsEqual': '\u2AB0̸', + 'NotSucceedsSlantEqual': '\u22E1', + 'NotSucceedsTilde': '\u227F̸', + 'NotSuperset': '\u2283⃒', + 'NotSupersetEqual': '\u2289', + 'NotTilde': '\u2241', + 'NotTildeEqual': '\u2244', + 'NotTildeFullEqual': '\u2247', + 'NotTildeTilde': '\u2249', + 'NotVerticalBar': '\u2224', + 'npar': '\u2226', + 'nparallel': '\u2226', + 'nparsl': '\u2AFD⃥', + 'npart': '\u2202̸', + 'npolint': '\u2A14', + 'npr': '\u2280', + 'nprcue': '\u22E0', + 'npre': '\u2AAF̸', + 'nprec': '\u2280', + 'npreceq': '\u2AAF̸', + 'nrarr': '\u219B', + 'nrArr': '\u21CF', + 'nrarrc': '\u2933̸', + 'nrarrw': '\u219D̸', + 'nrightarrow': '\u219B', + 'nRightarrow': '\u21CF', + 'nrtri': '\u22EB', + 'nrtrie': '\u22ED', + 'nsc': '\u2281', + 'nsccue': '\u22E1', + 'nsce': '\u2AB0̸', + 'nscr': '\uD835\uDCC3', + 'Nscr': '\uD835\uDCA9', + 'nshortmid': '\u2224', + 'nshortparallel': '\u2226', + 'nsim': '\u2241', + 'nsime': '\u2244', + 'nsimeq': '\u2244', + 'nsmid': '\u2224', + 'nspar': '\u2226', + 'nsqsube': '\u22E2', + 'nsqsupe': '\u22E3', + 'nsub': '\u2284', + 'nsube': '\u2288', + 'nsubE': '\u2AC5̸', + 'nsubset': '\u2282⃒', + 'nsubseteq': '\u2288', + 'nsubseteqq': '\u2AC5̸', + 'nsucc': '\u2281', + 'nsucceq': '\u2AB0̸', + 'nsup': '\u2285', + 'nsupe': '\u2289', + 'nsupE': '\u2AC6̸', + 'nsupset': '\u2283⃒', + 'nsupseteq': '\u2289', + 'nsupseteqq': '\u2AC6̸', + 'ntgl': '\u2279', + 'ntilde': 'ñ', + 'Ntilde': 'Ñ', + 'ntlg': '\u2278', + 'ntriangleleft': '\u22EA', + 'ntrianglelefteq': '\u22EC', + 'ntriangleright': '\u22EB', + 'ntrianglerighteq': '\u22ED', + 'nu': 'ν', + 'Nu': 'Ν', + 'num': '#', + 'numero': '\u2116', + 'numsp': '\u2007', + 'nvap': '\u224D⃒', + 'nvdash': '\u22AC', + 'nvDash': '\u22AD', + 'nVdash': '\u22AE', + 'nVDash': '\u22AF', + 'nvge': '\u2265⃒', + 'nvgt': '>⃒', + 'nvHarr': '\u2904', + 'nvinfin': '\u29DE', + 'nvlArr': '\u2902', + 'nvle': '\u2264⃒', + 'nvlt': '<⃒', + 'nvltrie': '\u22B4⃒', + 'nvrArr': '\u2903', + 'nvrtrie': '\u22B5⃒', + 'nvsim': '\u223C⃒', + 'nwarhk': '\u2923', + 'nwarr': '\u2196', + 'nwArr': '\u21D6', + 'nwarrow': '\u2196', + 'nwnear': '\u2927', + 'oacute': 'ó', + 'Oacute': 'Ó', + 'oast': '\u229B', + 'ocir': '\u229A', + 'ocirc': 'ô', + 'Ocirc': 'Ô', + 'ocy': 'о', + 'Ocy': 'О', + 'odash': '\u229D', + 'odblac': 'ő', + 'Odblac': 'Ő', + 'odiv': '\u2A38', + 'odot': '\u2299', + 'odsold': '\u29BC', + 'oelig': 'œ', + 'OElig': 'Œ', + 'ofcir': '\u29BF', + 'ofr': '\uD835\uDD2C', + 'Ofr': '\uD835\uDD12', + 'ogon': '\u02DB', + 'ograve': 'ò', + 'Ograve': 'Ò', + 'ogt': '\u29C1', + 'ohbar': '\u29B5', + 'ohm': 'Ω', + 'oint': '\u222E', + 'olarr': '\u21BA', + 'olcir': '\u29BE', + 'olcross': '\u29BB', + 'oline': '\u203E', + 'olt': '\u29C0', + 'omacr': 'ō', + 'Omacr': 'Ō', + 'omega': 'ω', + 'Omega': 'Ω', + 'omicron': 'ο', + 'Omicron': 'Ο', + 'omid': '\u29B6', + 'ominus': '\u2296', + 'oopf': '\uD835\uDD60', + 'Oopf': '\uD835\uDD46', + 'opar': '\u29B7', + 'OpenCurlyDoubleQuote': '\u201C', + 'OpenCurlyQuote': '\u2018', + 'operp': '\u29B9', + 'oplus': '\u2295', + 'or': '\u2228', + 'Or': '\u2A54', + 'orarr': '\u21BB', + 'ord': '\u2A5D', + 'order': 'ℴ', + 'orderof': 'ℴ', + 'ordf': 'ª', + 'ordm': 'º', + 'origof': '\u22B6', + 'oror': '\u2A56', + 'orslope': '\u2A57', + 'orv': '\u2A5B', + 'oS': '\u24C8', + 'oscr': 'ℴ', + 'Oscr': '\uD835\uDCAA', + 'oslash': 'ø', + 'Oslash': 'Ø', + 'osol': '\u2298', + 'otilde': 'õ', + 'Otilde': 'Õ', + 'otimes': '\u2297', + 'Otimes': '\u2A37', + 'otimesas': '\u2A36', + 'ouml': 'ö', + 'Ouml': 'Ö', + 'ovbar': '\u233D', + 'OverBar': '\u203E', + 'OverBrace': '\u23DE', + 'OverBracket': '\u23B4', + 'OverParenthesis': '\u23DC', + 'par': '\u2225', + 'para': '\xB6', + 'parallel': '\u2225', + 'parsim': '\u2AF3', + 'parsl': '\u2AFD', + 'part': '\u2202', + 'PartialD': '\u2202', + 'pcy': 'п', + 'Pcy': 'П', + 'percnt': '%', + 'period': '.', + 'permil': '\u2030', + 'perp': '\u22A5', + 'pertenk': '\u2031', + 'pfr': '\uD835\uDD2D', + 'Pfr': '\uD835\uDD13', + 'phi': 'φ', + 'Phi': 'Φ', + 'phiv': 'ϕ', + 'phmmat': 'ℳ', + 'phone': '\u260E', + 'pi': 'π', + 'Pi': 'Π', + 'pitchfork': '\u22D4', + 'piv': 'ϖ', + 'planck': 'ℏ', + 'planckh': 'ℎ', + 'plankv': 'ℏ', + 'plus': '+', + 'plusacir': '\u2A23', + 'plusb': '\u229E', + 'pluscir': '\u2A22', + 'plusdo': '\u2214', + 'plusdu': '\u2A25', + 'pluse': '\u2A72', + 'PlusMinus': '\xB1', + 'plusmn': '\xB1', + 'plussim': '\u2A26', + 'plustwo': '\u2A27', + 'pm': '\xB1', + 'Poincareplane': 'ℌ', + 'pointint': '\u2A15', + 'popf': '\uD835\uDD61', + 'Popf': 'ℙ', + 'pound': '\xA3', + 'pr': '\u227A', + 'Pr': '\u2ABB', + 'prap': '\u2AB7', + 'prcue': '\u227C', + 'pre': '\u2AAF', + 'prE': '\u2AB3', + 'prec': '\u227A', + 'precapprox': '\u2AB7', + 'preccurlyeq': '\u227C', + 'Precedes': '\u227A', + 'PrecedesEqual': '\u2AAF', + 'PrecedesSlantEqual': '\u227C', + 'PrecedesTilde': '\u227E', + 'preceq': '\u2AAF', + 'precnapprox': '\u2AB9', + 'precneqq': '\u2AB5', + 'precnsim': '\u22E8', + 'precsim': '\u227E', + 'prime': '\u2032', + 'Prime': '\u2033', + 'primes': 'ℙ', + 'prnap': '\u2AB9', + 'prnE': '\u2AB5', + 'prnsim': '\u22E8', + 'prod': '\u220F', + 'Product': '\u220F', + 'profalar': '\u232E', + 'profline': '\u2312', + 'profsurf': '\u2313', + 'prop': '\u221D', + 'Proportion': '\u2237', + 'Proportional': '\u221D', + 'propto': '\u221D', + 'prsim': '\u227E', + 'prurel': '\u22B0', + 'pscr': '\uD835\uDCC5', + 'Pscr': '\uD835\uDCAB', + 'psi': 'ψ', + 'Psi': 'Ψ', + 'puncsp': '\u2008', + 'qfr': '\uD835\uDD2E', + 'Qfr': '\uD835\uDD14', + 'qint': '\u2A0C', + 'qopf': '\uD835\uDD62', + 'Qopf': 'ℚ', + 'qprime': '\u2057', + 'qscr': '\uD835\uDCC6', + 'Qscr': '\uD835\uDCAC', + 'quaternions': 'ℍ', + 'quatint': '\u2A16', + 'quest': '?', + 'questeq': '\u225F', + 'quot': '"', + 'QUOT': '"', + 'rAarr': '\u21DB', + 'race': '\u223Ḏ', + 'racute': 'ŕ', + 'Racute': 'Ŕ', + 'radic': '\u221A', + 'raemptyv': '\u29B3', + 'rang': '\u27E9', + 'Rang': '\u27EB', + 'rangd': '\u2992', + 'range': '\u29A5', + 'rangle': '\u27E9', + 'raquo': '\xBB', + 'rarr': '\u2192', + 'rArr': '\u21D2', + 'Rarr': '\u21A0', + 'rarrap': '\u2975', + 'rarrb': '\u21E5', + 'rarrbfs': '\u2920', + 'rarrc': '\u2933', + 'rarrfs': '\u291E', + 'rarrhk': '\u21AA', + 'rarrlp': '\u21AC', + 'rarrpl': '\u2945', + 'rarrsim': '\u2974', + 'rarrtl': '\u21A3', + 'Rarrtl': '\u2916', + 'rarrw': '\u219D', + 'ratail': '\u291A', + 'rAtail': '\u291C', + 'ratio': '\u2236', + 'rationals': 'ℚ', + 'rbarr': '\u290D', + 'rBarr': '\u290F', + 'RBarr': '\u2910', + 'rbbrk': '\u2773', + 'rbrace': '}', + 'rbrack': ']', + 'rbrke': '\u298C', + 'rbrksld': '\u298E', + 'rbrkslu': '\u2990', + 'rcaron': 'ř', + 'Rcaron': 'Ř', + 'rcedil': 'ŗ', + 'Rcedil': 'Ŗ', + 'rceil': '\u2309', + 'rcub': '}', + 'rcy': 'р', + 'Rcy': 'Р', + 'rdca': '\u2937', + 'rdldhar': '\u2969', + 'rdquo': '\u201D', + 'rdquor': '\u201D', + 'rdsh': '\u21B3', + 'Re': 'ℜ', + 'real': 'ℜ', + 'realine': 'ℛ', + 'realpart': 'ℜ', + 'reals': 'ℝ', + 'rect': '\u25AD', + 'reg': '\xAE', + 'REG': '\xAE', + 'ReverseElement': '\u220B', + 'ReverseEquilibrium': '\u21CB', + 'ReverseUpEquilibrium': '\u296F', + 'rfisht': '\u297D', + 'rfloor': '\u230B', + 'rfr': '\uD835\uDD2F', + 'Rfr': 'ℜ', + 'rHar': '\u2964', + 'rhard': '\u21C1', + 'rharu': '\u21C0', + 'rharul': '\u296C', + 'rho': 'ρ', + 'Rho': 'Ρ', + 'rhov': 'ϱ', + 'RightAngleBracket': '\u27E9', + 'rightarrow': '\u2192', + 'Rightarrow': '\u21D2', + 'RightArrow': '\u2192', + 'RightArrowBar': '\u21E5', + 'RightArrowLeftArrow': '\u21C4', + 'rightarrowtail': '\u21A3', + 'RightCeiling': '\u2309', + 'RightDoubleBracket': '\u27E7', + 'RightDownTeeVector': '\u295D', + 'RightDownVector': '\u21C2', + 'RightDownVectorBar': '\u2955', + 'RightFloor': '\u230B', + 'rightharpoondown': '\u21C1', + 'rightharpoonup': '\u21C0', + 'rightleftarrows': '\u21C4', + 'rightleftharpoons': '\u21CC', + 'rightrightarrows': '\u21C9', + 'rightsquigarrow': '\u219D', + 'RightTee': '\u22A2', + 'RightTeeArrow': '\u21A6', + 'RightTeeVector': '\u295B', + 'rightthreetimes': '\u22CC', + 'RightTriangle': '\u22B3', + 'RightTriangleBar': '\u29D0', + 'RightTriangleEqual': '\u22B5', + 'RightUpDownVector': '\u294F', + 'RightUpTeeVector': '\u295C', + 'RightUpVector': '\u21BE', + 'RightUpVectorBar': '\u2954', + 'RightVector': '\u21C0', + 'RightVectorBar': '\u2953', + 'ring': '\u02DA', + 'risingdotseq': '\u2253', + 'rlarr': '\u21C4', + 'rlhar': '\u21CC', + 'rlm': '\u200F', + 'rmoust': '\u23B1', + 'rmoustache': '\u23B1', + 'rnmid': '\u2AEE', + 'roang': '\u27ED', + 'roarr': '\u21FE', + 'robrk': '\u27E7', + 'ropar': '\u2986', + 'ropf': '\uD835\uDD63', + 'Ropf': 'ℝ', + 'roplus': '\u2A2E', + 'rotimes': '\u2A35', + 'RoundImplies': '\u2970', + 'rpar': ')', + 'rpargt': '\u2994', + 'rppolint': '\u2A12', + 'rrarr': '\u21C9', + 'Rrightarrow': '\u21DB', + 'rsaquo': '\u203A', + 'rscr': '\uD835\uDCC7', + 'Rscr': 'ℛ', + 'rsh': '\u21B1', + 'Rsh': '\u21B1', + 'rsqb': ']', + 'rsquo': '\u2019', + 'rsquor': '\u2019', + 'rthree': '\u22CC', + 'rtimes': '\u22CA', + 'rtri': '\u25B9', + 'rtrie': '\u22B5', + 'rtrif': '\u25B8', + 'rtriltri': '\u29CE', + 'RuleDelayed': '\u29F4', + 'ruluhar': '\u2968', + 'rx': '\u211E', + 'sacute': 'ś', + 'Sacute': 'Ś', + 'sbquo': '\u201A', + 'sc': '\u227B', + 'Sc': '\u2ABC', + 'scap': '\u2AB8', + 'scaron': 'š', + 'Scaron': 'Š', + 'sccue': '\u227D', + 'sce': '\u2AB0', + 'scE': '\u2AB4', + 'scedil': 'ş', + 'Scedil': 'Ş', + 'scirc': 'ŝ', + 'Scirc': 'Ŝ', + 'scnap': '\u2ABA', + 'scnE': '\u2AB6', + 'scnsim': '\u22E9', + 'scpolint': '\u2A13', + 'scsim': '\u227F', + 'scy': 'с', + 'Scy': 'С', + 'sdot': '\u22C5', + 'sdotb': '\u22A1', + 'sdote': '\u2A66', + 'searhk': '\u2925', + 'searr': '\u2198', + 'seArr': '\u21D8', + 'searrow': '\u2198', + 'sect': '\xA7', + 'semi': ';', + 'seswar': '\u2929', + 'setminus': '\u2216', + 'setmn': '\u2216', + 'sext': '\u2736', + 'sfr': '\uD835\uDD30', + 'Sfr': '\uD835\uDD16', + 'sfrown': '\u2322', + 'sharp': '\u266F', + 'shchcy': 'щ', + 'SHCHcy': 'Щ', + 'shcy': 'ш', + 'SHcy': 'Ш', + 'ShortDownArrow': '\u2193', + 'ShortLeftArrow': '\u2190', + 'shortmid': '\u2223', + 'shortparallel': '\u2225', + 'ShortRightArrow': '\u2192', + 'ShortUpArrow': '\u2191', + 'shy': '\xAD', + 'sigma': 'σ', + 'Sigma': 'Σ', + 'sigmaf': 'ς', + 'sigmav': 'ς', + 'sim': '\u223C', + 'simdot': '\u2A6A', + 'sime': '\u2243', + 'simeq': '\u2243', + 'simg': '\u2A9E', + 'simgE': '\u2AA0', + 'siml': '\u2A9D', + 'simlE': '\u2A9F', + 'simne': '\u2246', + 'simplus': '\u2A24', + 'simrarr': '\u2972', + 'slarr': '\u2190', + 'SmallCircle': '\u2218', + 'smallsetminus': '\u2216', + 'smashp': '\u2A33', + 'smeparsl': '\u29E4', + 'smid': '\u2223', + 'smile': '\u2323', + 'smt': '\u2AAA', + 'smte': '\u2AAC', + 'smtes': '\u2AAC︀', + 'softcy': 'ь', + 'SOFTcy': 'Ь', + 'sol': '/', + 'solb': '\u29C4', + 'solbar': '\u233F', + 'sopf': '\uD835\uDD64', + 'Sopf': '\uD835\uDD4A', + 'spades': '\u2660', + 'spadesuit': '\u2660', + 'spar': '\u2225', + 'sqcap': '\u2293', + 'sqcaps': '\u2293︀', + 'sqcup': '\u2294', + 'sqcups': '\u2294︀', + 'Sqrt': '\u221A', + 'sqsub': '\u228F', + 'sqsube': '\u2291', + 'sqsubset': '\u228F', + 'sqsubseteq': '\u2291', + 'sqsup': '\u2290', + 'sqsupe': '\u2292', + 'sqsupset': '\u2290', + 'sqsupseteq': '\u2292', + 'squ': '\u25A1', + 'square': '\u25A1', + 'Square': '\u25A1', + 'SquareIntersection': '\u2293', + 'SquareSubset': '\u228F', + 'SquareSubsetEqual': '\u2291', + 'SquareSuperset': '\u2290', + 'SquareSupersetEqual': '\u2292', + 'SquareUnion': '\u2294', + 'squarf': '\u25AA', + 'squf': '\u25AA', + 'srarr': '\u2192', + 'sscr': '\uD835\uDCC8', + 'Sscr': '\uD835\uDCAE', + 'ssetmn': '\u2216', + 'ssmile': '\u2323', + 'sstarf': '\u22C6', + 'star': '\u2606', + 'Star': '\u22C6', + 'starf': '\u2605', + 'straightepsilon': 'ϵ', + 'straightphi': 'ϕ', + 'strns': '\xAF', + 'sub': '\u2282', + 'Sub': '\u22D0', + 'subdot': '\u2ABD', + 'sube': '\u2286', + 'subE': '\u2AC5', + 'subedot': '\u2AC3', + 'submult': '\u2AC1', + 'subne': '\u228A', + 'subnE': '\u2ACB', + 'subplus': '\u2ABF', + 'subrarr': '\u2979', + 'subset': '\u2282', + 'Subset': '\u22D0', + 'subseteq': '\u2286', + 'subseteqq': '\u2AC5', + 'SubsetEqual': '\u2286', + 'subsetneq': '\u228A', + 'subsetneqq': '\u2ACB', + 'subsim': '\u2AC7', + 'subsub': '\u2AD5', + 'subsup': '\u2AD3', + 'succ': '\u227B', + 'succapprox': '\u2AB8', + 'succcurlyeq': '\u227D', + 'Succeeds': '\u227B', + 'SucceedsEqual': '\u2AB0', + 'SucceedsSlantEqual': '\u227D', + 'SucceedsTilde': '\u227F', + 'succeq': '\u2AB0', + 'succnapprox': '\u2ABA', + 'succneqq': '\u2AB6', + 'succnsim': '\u22E9', + 'succsim': '\u227F', + 'SuchThat': '\u220B', + 'sum': '\u2211', + 'Sum': '\u2211', + 'sung': '\u266A', + 'sup': '\u2283', + 'Sup': '\u22D1', + 'sup1': '\xB9', + 'sup2': '\xB2', + 'sup3': '\xB3', + 'supdot': '\u2ABE', + 'supdsub': '\u2AD8', + 'supe': '\u2287', + 'supE': '\u2AC6', + 'supedot': '\u2AC4', + 'Superset': '\u2283', + 'SupersetEqual': '\u2287', + 'suphsol': '\u27C9', + 'suphsub': '\u2AD7', + 'suplarr': '\u297B', + 'supmult': '\u2AC2', + 'supne': '\u228B', + 'supnE': '\u2ACC', + 'supplus': '\u2AC0', + 'supset': '\u2283', + 'Supset': '\u22D1', + 'supseteq': '\u2287', + 'supseteqq': '\u2AC6', + 'supsetneq': '\u228B', + 'supsetneqq': '\u2ACC', + 'supsim': '\u2AC8', + 'supsub': '\u2AD4', + 'supsup': '\u2AD6', + 'swarhk': '\u2926', + 'swarr': '\u2199', + 'swArr': '\u21D9', + 'swarrow': '\u2199', + 'swnwar': '\u292A', + 'szlig': 'ß', + 'Tab': '\t', + 'target': '\u2316', + 'tau': 'τ', + 'Tau': 'Τ', + 'tbrk': '\u23B4', + 'tcaron': 'ť', + 'Tcaron': 'Ť', + 'tcedil': 'ţ', + 'Tcedil': 'Ţ', + 'tcy': 'т', + 'Tcy': 'Т', + 'tdot': '⃛', + 'telrec': '\u2315', + 'tfr': '\uD835\uDD31', + 'Tfr': '\uD835\uDD17', + 'there4': '\u2234', + 'therefore': '\u2234', + 'Therefore': '\u2234', + 'theta': 'θ', + 'Theta': 'Θ', + 'thetasym': 'ϑ', + 'thetav': 'ϑ', + 'thickapprox': '\u2248', + 'thicksim': '\u223C', + 'ThickSpace': '\u205F\u200A', + 'thinsp': '\u2009', + 'ThinSpace': '\u2009', + 'thkap': '\u2248', + 'thksim': '\u223C', + 'thorn': 'þ', + 'THORN': 'Þ', + 'tilde': '\u02DC', + 'Tilde': '\u223C', + 'TildeEqual': '\u2243', + 'TildeFullEqual': '\u2245', + 'TildeTilde': '\u2248', + 'times': '\xD7', + 'timesb': '\u22A0', + 'timesbar': '\u2A31', + 'timesd': '\u2A30', + 'tint': '\u222D', + 'toea': '\u2928', + 'top': '\u22A4', + 'topbot': '\u2336', + 'topcir': '\u2AF1', + 'topf': '\uD835\uDD65', + 'Topf': '\uD835\uDD4B', + 'topfork': '\u2ADA', + 'tosa': '\u2929', + 'tprime': '\u2034', + 'trade': '\u2122', + 'TRADE': '\u2122', + 'triangle': '\u25B5', + 'triangledown': '\u25BF', + 'triangleleft': '\u25C3', + 'trianglelefteq': '\u22B4', + 'triangleq': '\u225C', + 'triangleright': '\u25B9', + 'trianglerighteq': '\u22B5', + 'tridot': '\u25EC', + 'trie': '\u225C', + 'triminus': '\u2A3A', + 'TripleDot': '⃛', + 'triplus': '\u2A39', + 'trisb': '\u29CD', + 'tritime': '\u2A3B', + 'trpezium': '\u23E2', + 'tscr': '\uD835\uDCC9', + 'Tscr': '\uD835\uDCAF', + 'tscy': 'ц', + 'TScy': 'Ц', + 'tshcy': 'ћ', + 'TSHcy': 'Ћ', + 'tstrok': 'ŧ', + 'Tstrok': 'Ŧ', + 'twixt': '\u226C', + 'twoheadleftarrow': '\u219E', + 'twoheadrightarrow': '\u21A0', + 'uacute': 'ú', + 'Uacute': 'Ú', + 'uarr': '\u2191', + 'uArr': '\u21D1', + 'Uarr': '\u219F', + 'Uarrocir': '\u2949', + 'ubrcy': 'ў', + 'Ubrcy': 'Ў', + 'ubreve': 'ŭ', + 'Ubreve': 'Ŭ', + 'ucirc': 'û', + 'Ucirc': 'Û', + 'ucy': 'у', + 'Ucy': 'У', + 'udarr': '\u21C5', + 'udblac': 'ű', + 'Udblac': 'Ű', + 'udhar': '\u296E', + 'ufisht': '\u297E', + 'ufr': '\uD835\uDD32', + 'Ufr': '\uD835\uDD18', + 'ugrave': 'ù', + 'Ugrave': 'Ù', + 'uHar': '\u2963', + 'uharl': '\u21BF', + 'uharr': '\u21BE', + 'uhblk': '\u2580', + 'ulcorn': '\u231C', + 'ulcorner': '\u231C', + 'ulcrop': '\u230F', + 'ultri': '\u25F8', + 'umacr': 'ū', + 'Umacr': 'Ū', + 'uml': '\xA8', + 'UnderBar': '_', + 'UnderBrace': '\u23DF', + 'UnderBracket': '\u23B5', + 'UnderParenthesis': '\u23DD', + 'Union': '\u22C3', + 'UnionPlus': '\u228E', + 'uogon': 'ų', + 'Uogon': 'Ų', + 'uopf': '\uD835\uDD66', + 'Uopf': '\uD835\uDD4C', + 'uparrow': '\u2191', + 'Uparrow': '\u21D1', + 'UpArrow': '\u2191', + 'UpArrowBar': '\u2912', + 'UpArrowDownArrow': '\u21C5', + 'updownarrow': '\u2195', + 'Updownarrow': '\u21D5', + 'UpDownArrow': '\u2195', + 'UpEquilibrium': '\u296E', + 'upharpoonleft': '\u21BF', + 'upharpoonright': '\u21BE', + 'uplus': '\u228E', + 'UpperLeftArrow': '\u2196', + 'UpperRightArrow': '\u2197', + 'upsi': 'υ', + 'Upsi': 'ϒ', + 'upsih': 'ϒ', + 'upsilon': 'υ', + 'Upsilon': 'Υ', + 'UpTee': '\u22A5', + 'UpTeeArrow': '\u21A5', + 'upuparrows': '\u21C8', + 'urcorn': '\u231D', + 'urcorner': '\u231D', + 'urcrop': '\u230E', + 'uring': 'ů', + 'Uring': 'Ů', + 'urtri': '\u25F9', + 'uscr': '\uD835\uDCCA', + 'Uscr': '\uD835\uDCB0', + 'utdot': '\u22F0', + 'utilde': 'ũ', + 'Utilde': 'Ũ', + 'utri': '\u25B5', + 'utrif': '\u25B4', + 'uuarr': '\u21C8', + 'uuml': 'ü', + 'Uuml': 'Ü', + 'uwangle': '\u29A7', + 'vangrt': '\u299C', + 'varepsilon': 'ϵ', + 'varkappa': 'ϰ', + 'varnothing': '\u2205', + 'varphi': 'ϕ', + 'varpi': 'ϖ', + 'varpropto': '\u221D', + 'varr': '\u2195', + 'vArr': '\u21D5', + 'varrho': 'ϱ', + 'varsigma': 'ς', + 'varsubsetneq': '\u228A︀', + 'varsubsetneqq': '\u2ACB︀', + 'varsupsetneq': '\u228B︀', + 'varsupsetneqq': '\u2ACC︀', + 'vartheta': 'ϑ', + 'vartriangleleft': '\u22B2', + 'vartriangleright': '\u22B3', + 'vBar': '\u2AE8', + 'Vbar': '\u2AEB', + 'vBarv': '\u2AE9', + 'vcy': 'в', + 'Vcy': 'В', + 'vdash': '\u22A2', + 'vDash': '\u22A8', + 'Vdash': '\u22A9', + 'VDash': '\u22AB', + 'Vdashl': '\u2AE6', + 'vee': '\u2228', + 'Vee': '\u22C1', + 'veebar': '\u22BB', + 'veeeq': '\u225A', + 'vellip': '\u22EE', + 'verbar': '|', + 'Verbar': '\u2016', + 'vert': '|', + 'Vert': '\u2016', + 'VerticalBar': '\u2223', + 'VerticalLine': '|', + 'VerticalSeparator': '\u2758', + 'VerticalTilde': '\u2240', + 'VeryThinSpace': '\u200A', + 'vfr': '\uD835\uDD33', + 'Vfr': '\uD835\uDD19', + 'vltri': '\u22B2', + 'vnsub': '\u2282⃒', + 'vnsup': '\u2283⃒', + 'vopf': '\uD835\uDD67', + 'Vopf': '\uD835\uDD4D', + 'vprop': '\u221D', + 'vrtri': '\u22B3', + 'vscr': '\uD835\uDCCB', + 'Vscr': '\uD835\uDCB1', + 'vsubne': '\u228A︀', + 'vsubnE': '\u2ACB︀', + 'vsupne': '\u228B︀', + 'vsupnE': '\u2ACC︀', + 'Vvdash': '\u22AA', + 'vzigzag': '\u299A', + 'wcirc': 'ŵ', + 'Wcirc': 'Ŵ', + 'wedbar': '\u2A5F', + 'wedge': '\u2227', + 'Wedge': '\u22C0', + 'wedgeq': '\u2259', + 'weierp': '\u2118', + 'wfr': '\uD835\uDD34', + 'Wfr': '\uD835\uDD1A', + 'wopf': '\uD835\uDD68', + 'Wopf': '\uD835\uDD4E', + 'wp': '\u2118', + 'wr': '\u2240', + 'wreath': '\u2240', + 'wscr': '\uD835\uDCCC', + 'Wscr': '\uD835\uDCB2', + 'xcap': '\u22C2', + 'xcirc': '\u25EF', + 'xcup': '\u22C3', + 'xdtri': '\u25BD', + 'xfr': '\uD835\uDD35', + 'Xfr': '\uD835\uDD1B', + 'xharr': '\u27F7', + 'xhArr': '\u27FA', + 'xi': 'ξ', + 'Xi': 'Ξ', + 'xlarr': '\u27F5', + 'xlArr': '\u27F8', + 'xmap': '\u27FC', + 'xnis': '\u22FB', + 'xodot': '\u2A00', + 'xopf': '\uD835\uDD69', + 'Xopf': '\uD835\uDD4F', + 'xoplus': '\u2A01', + 'xotime': '\u2A02', + 'xrarr': '\u27F6', + 'xrArr': '\u27F9', + 'xscr': '\uD835\uDCCD', + 'Xscr': '\uD835\uDCB3', + 'xsqcup': '\u2A06', + 'xuplus': '\u2A04', + 'xutri': '\u25B3', + 'xvee': '\u22C1', + 'xwedge': '\u22C0', + 'yacute': 'ý', + 'Yacute': 'Ý', + 'yacy': 'я', + 'YAcy': 'Я', + 'ycirc': 'ŷ', + 'Ycirc': 'Ŷ', + 'ycy': 'ы', + 'Ycy': 'Ы', + 'yen': '\xA5', + 'yfr': '\uD835\uDD36', + 'Yfr': '\uD835\uDD1C', + 'yicy': 'ї', + 'YIcy': 'Ї', + 'yopf': '\uD835\uDD6A', + 'Yopf': '\uD835\uDD50', + 'yscr': '\uD835\uDCCE', + 'Yscr': '\uD835\uDCB4', + 'yucy': 'ю', + 'YUcy': 'Ю', + 'yuml': 'ÿ', + 'Yuml': 'Ÿ', + 'zacute': 'ź', + 'Zacute': 'Ź', + 'zcaron': 'ž', + 'Zcaron': 'Ž', + 'zcy': 'з', + 'Zcy': 'З', + 'zdot': 'ż', + 'Zdot': 'Ż', + 'zeetrf': 'ℨ', + 'ZeroWidthSpace': '\u200B', + 'zeta': 'ζ', + 'Zeta': 'Ζ', + 'zfr': '\uD835\uDD37', + 'Zfr': 'ℨ', + 'zhcy': 'ж', + 'ZHcy': 'Ж', + 'zigrarr': '\u21DD', + 'zopf': '\uD835\uDD6B', + 'Zopf': 'ℤ', + 'zscr': '\uD835\uDCCF', + 'Zscr': '\uD835\uDCB5', + 'zwj': '‍', + 'zwnj': '‌' + }; + var decodeMapLegacy = { + 'aacute': 'á', + 'Aacute': 'Á', + 'acirc': 'â', + 'Acirc': 'Â', + 'acute': '\xB4', + 'aelig': 'æ', + 'AElig': 'Æ', + 'agrave': 'à', + 'Agrave': 'À', + 'amp': '&', + 'AMP': '&', + 'aring': 'å', + 'Aring': 'Å', + 'atilde': 'ã', + 'Atilde': 'Ã', + 'auml': 'ä', + 'Auml': 'Ä', + 'brvbar': '\xA6', + 'ccedil': 'ç', + 'Ccedil': 'Ç', + 'cedil': '\xB8', + 'cent': '\xA2', + 'copy': '\xA9', + 'COPY': '\xA9', + 'curren': '\xA4', + 'deg': '\xB0', + 'divide': '\xF7', + 'eacute': 'é', + 'Eacute': 'É', + 'ecirc': 'ê', + 'Ecirc': 'Ê', + 'egrave': 'è', + 'Egrave': 'È', + 'eth': 'ð', + 'ETH': 'Ð', + 'euml': 'ë', + 'Euml': 'Ë', + 'frac12': '\xBD', + 'frac14': '\xBC', + 'frac34': '\xBE', + 'gt': '>', + 'GT': '>', + 'iacute': 'í', + 'Iacute': 'Í', + 'icirc': 'î', + 'Icirc': 'Î', + 'iexcl': '\xA1', + 'igrave': 'ì', + 'Igrave': 'Ì', + 'iquest': '\xBF', + 'iuml': 'ï', + 'Iuml': 'Ï', + 'laquo': '\xAB', + 'lt': '<', + 'LT': '<', + 'macr': '\xAF', + 'micro': 'µ', + 'middot': '\xB7', + 'nbsp': '\xA0', + 'not': '\xAC', + 'ntilde': 'ñ', + 'Ntilde': 'Ñ', + 'oacute': 'ó', + 'Oacute': 'Ó', + 'ocirc': 'ô', + 'Ocirc': 'Ô', + 'ograve': 'ò', + 'Ograve': 'Ò', + 'ordf': 'ª', + 'ordm': 'º', + 'oslash': 'ø', + 'Oslash': 'Ø', + 'otilde': 'õ', + 'Otilde': 'Õ', + 'ouml': 'ö', + 'Ouml': 'Ö', + 'para': '\xB6', + 'plusmn': '\xB1', + 'pound': '\xA3', + 'quot': '"', + 'QUOT': '"', + 'raquo': '\xBB', + 'reg': '\xAE', + 'REG': '\xAE', + 'sect': '\xA7', + 'shy': '\xAD', + 'sup1': '\xB9', + 'sup2': '\xB2', + 'sup3': '\xB3', + 'szlig': 'ß', + 'thorn': 'þ', + 'THORN': 'Þ', + 'times': '\xD7', + 'uacute': 'ú', + 'Uacute': 'Ú', + 'ucirc': 'û', + 'Ucirc': 'Û', + 'ugrave': 'ù', + 'Ugrave': 'Ù', + 'uml': '\xA8', + 'uuml': 'ü', + 'Uuml': 'Ü', + 'yacute': 'ý', + 'Yacute': 'Ý', + 'yen': '\xA5', + 'yuml': 'ÿ' + }; + var decodeMapNumeric = { + '0': '\uFFFD', + '128': '\u20AC', + '130': '\u201A', + '131': 'ƒ', + '132': '\u201E', + '133': '\u2026', + '134': '\u2020', + '135': '\u2021', + '136': 'ˆ', + '137': '\u2030', + '138': 'Š', + '139': '\u2039', + '140': 'Œ', + '142': 'Ž', + '145': '\u2018', + '146': '\u2019', + '147': '\u201C', + '148': '\u201D', + '149': '\u2022', + '150': '\u2013', + '151': '\u2014', + '152': '\u02DC', + '153': '\u2122', + '154': 'š', + '155': '\u203A', + '156': 'œ', + '158': 'ž', + '159': 'Ÿ' + }; + var invalidReferenceCodePoints = [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 11, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 64976, + 64977, + 64978, + 64979, + 64980, + 64981, + 64982, + 64983, + 64984, + 64985, + 64986, + 64987, + 64988, + 64989, + 64990, + 64991, + 64992, + 64993, + 64994, + 64995, + 64996, + 64997, + 64998, + 64999, + 65000, + 65001, + 65002, + 65003, + 65004, + 65005, + 65006, + 65007, + 65534, + 65535, + 131070, + 131071, + 196606, + 196607, + 262142, + 262143, + 327678, + 327679, + 393214, + 393215, + 458750, + 458751, + 524286, + 524287, + 589822, + 589823, + 655358, + 655359, + 720894, + 720895, + 786430, + 786431, + 851966, + 851967, + 917502, + 917503, + 983038, + 983039, + 1048574, + 1048575, + 1114110, + 1114111 + ]; + var stringFromCharCode = String.fromCharCode; + var object = {}; + var hasOwnProperty = object.hasOwnProperty; + var has = function (object, propertyName) { + return hasOwnProperty.call(object, propertyName); + }; + var contains = function (array, value) { + var index = -1; + var length = array.length; + while (++index < length) { + if (array[index] == value) { + return true; + } + } + return false; + }; + var merge = function (options, defaults) { + if (!options) { + return defaults; + } + var result = {}; + var key; + for (key in defaults) { + result[key] = has(options, key) ? options[key] : defaults[key]; + } + return result; + }; + var codePointToSymbol = function (codePoint, strict) { + var output = ''; + if (codePoint >= 55296 && codePoint <= 57343 || codePoint > 1114111) { + if (strict) { + parseError('character reference outside the permissible Unicode range'); + } + return '\uFFFD'; + } + if (has(decodeMapNumeric, codePoint)) { + if (strict) { + parseError('disallowed character reference'); + } + return decodeMapNumeric[codePoint]; + } + if (strict && contains(invalidReferenceCodePoints, codePoint)) { + parseError('disallowed character reference'); + } + if (codePoint > 65535) { + codePoint -= 65536; + output += stringFromCharCode(codePoint >>> 10 & 1023 | 55296); + codePoint = 56320 | codePoint & 1023; + } + output += stringFromCharCode(codePoint); + return output; + }; + var hexEscape = function (codePoint) { + return '&#x' + codePoint.toString(16).toUpperCase() + ';'; + }; + var decEscape = function (codePoint) { + return '&#' + codePoint + ';'; + }; + var parseError = function (message) { + throw Error('Parse error: ' + message); + }; + var encode = function (string, options) { + options = merge(options, encode.options); + var strict = options.strict; + if (strict && regexInvalidRawCodePoint.test(string)) { + parseError('forbidden code point'); + } + var encodeEverything = options.encodeEverything; + var useNamedReferences = options.useNamedReferences; + var allowUnsafeSymbols = options.allowUnsafeSymbols; + var escapeCodePoint = options.decimal ? decEscape : hexEscape; + var escapeBmpSymbol = function (symbol) { + return escapeCodePoint(symbol.charCodeAt(0)); + }; + if (encodeEverything) { + string = string.replace(regexAsciiWhitelist, function (symbol) { + if (useNamedReferences && has(encodeMap, symbol)) { + return '&' + encodeMap[symbol] + ';'; + } + return escapeBmpSymbol(symbol); + }); + if (useNamedReferences) { + string = string.replace(/>\u20D2/g, '>⃒').replace(/<\u20D2/g, '<⃒').replace(/fj/g, 'fj'); + } + if (useNamedReferences) { + string = string.replace(regexEncodeNonAscii, function (string) { + return '&' + encodeMap[string] + ';'; + }); + } + } else if (useNamedReferences) { + if (!allowUnsafeSymbols) { + string = string.replace(regexEscape, function (string) { + return '&' + encodeMap[string] + ';'; + }); + } + string = string.replace(/>\u20D2/g, '>⃒').replace(/<\u20D2/g, '<⃒'); + string = string.replace(regexEncodeNonAscii, function (string) { + return '&' + encodeMap[string] + ';'; + }); + } else if (!allowUnsafeSymbols) { + string = string.replace(regexEscape, escapeBmpSymbol); + } + return string.replace(regexAstralSymbols, function ($0) { + var high = $0.charCodeAt(0); + var low = $0.charCodeAt(1); + var codePoint = (high - 55296) * 1024 + low - 56320 + 65536; + return escapeCodePoint(codePoint); + }).replace(regexBmpWhitelist, escapeBmpSymbol); + }; + encode.options = { + 'allowUnsafeSymbols': false, + 'encodeEverything': false, + 'strict': false, + 'useNamedReferences': false, + 'decimal': false + }; + var decode = function (html, options) { + options = merge(options, decode.options); + var strict = options.strict; + if (strict && regexInvalidEntity.test(html)) { + parseError('malformed character reference'); + } + return html.replace(regexDecode, function ($0, $1, $2, $3, $4, $5, $6, $7, $8) { + var codePoint; + var semicolon; + var decDigits; + var hexDigits; + var reference; + var next; + if ($1) { + reference = $1; + return decodeMap[reference]; + } + if ($2) { + reference = $2; + next = $3; + if (next && options.isAttributeValue) { + if (strict && next == '=') { + parseError('`&` did not start a character reference'); + } + return $0; + } else { + if (strict) { + parseError('named character reference was not terminated by a semicolon'); + } + return decodeMapLegacy[reference] + (next || ''); + } + } + if ($4) { + decDigits = $4; + semicolon = $5; + if (strict && !semicolon) { + parseError('character reference was not terminated by a semicolon'); + } + codePoint = parseInt(decDigits, 10); + return codePointToSymbol(codePoint, strict); + } + if ($6) { + hexDigits = $6; + semicolon = $7; + if (strict && !semicolon) { + parseError('character reference was not terminated by a semicolon'); + } + codePoint = parseInt(hexDigits, 16); + return codePointToSymbol(codePoint, strict); + } + if (strict) { + parseError('named character reference was not terminated by a semicolon'); + } + return $0; + }); + }; + decode.options = { + 'isAttributeValue': false, + 'strict': false + }; + var escape = function (string) { + return string.replace(regexEscape, function ($0) { + return escapeMap[$0]; + }); + }; + var he = { + 'version': '1.2.0', + 'encode': encode, + 'decode': decode, + 'escape': escape, + 'unescape': decode + }; + if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { + define('he@1.2.0#he', function () { + return he; + }); + } else if (freeExports && !freeExports.nodeType) { + if (freeModule) { + freeModule.exports = he; + } else { + for (var key in he) { + has(he, key) && (freeExports[key] = he[key]); + } + } + } else { + root.he = he; + } +}(this)); +/*can-simple-dom@1.4.2#lib/html-parser*/ +define('can-simple-dom@1.4.2#lib/html-parser', [ + 'require', + 'exports', + 'module', + 'he' +], function (require, exports, module) { + var he = require('he'); + function HTMLParser(tokenize, document, voidMap) { + this.tokenize = tokenize; + this.document = document; + this.voidMap = voidMap; + this.parentStack = []; + } + HTMLParser.prototype.isVoid = function (element) { + return this.voidMap[element.nodeName] === true; + }; + HTMLParser.prototype.pushElement = function (token) { + var el = this.document.createElement(token.tagName); + for (var i = 0; i < token.attributes.length; i++) { + var attr = token.attributes[i]; + if (attr[0] !== 'href' && attr[0] !== 'src') { + attr[1] = he.encode(attr[1]); + } + el.setAttribute(attr[0], attr[1]); + } + if (this.isVoid(el) || token.selfClosing) { + return this.appendChild(el); + } + this.parentStack.push(el); + }; + HTMLParser.prototype.popElement = function (token) { + var el = this.parentStack.pop(); + if (el.nodeName !== token.tagName.toUpperCase()) { + throw new Error('unbalanced tag'); + } + this.appendChild(el); + }; + HTMLParser.prototype.appendText = function (token) { + var text = this.document.createTextNode(token.chars); + this.appendChild(text); + }; + HTMLParser.prototype.appendComment = function (token) { + var comment = this.document.createComment(token.chars); + this.appendChild(comment); + }; + HTMLParser.prototype.appendChild = function (node) { + var parentNode = this.parentStack[this.parentStack.length - 1]; + parentNode.appendChild(node); + }; + HTMLParser.prototype.parse = function (html) { + var fragment = this.document.createDocumentFragment(); + this.parentStack.push(fragment); + var tokens = this.tokenize(html); + for (var i = 0, l = tokens.length; i < l; i++) { + var token = tokens[i]; + switch (token.type) { + case 'StartTag': + this.pushElement(token); + break; + case 'EndTag': + this.popElement(token); + break; + case 'Chars': + this.appendText(token); + break; + case 'Comment': + this.appendComment(token); + break; + } + } + return this.parentStack.pop(); + }; + module.exports = HTMLParser; +}); +/*can-simple-dom@1.4.2#lib/html-serializer*/ +define('can-simple-dom@1.4.2#lib/html-serializer', function (require, exports, module) { + var REG_ESCAPE_ALL = /[<>&]/g; + var REG_ESCAPE_PRESERVE_ENTITIES = /[<>]|&(?:#?[a-zA-Z0-9]+;)?/g; + function HTMLSerializer(voidMap) { + this.voidMap = voidMap; + } + HTMLSerializer.prototype.openTag = function (element) { + return '<' + element.nodeName.toLowerCase() + this.attributes(element.attributes) + '>'; + }; + HTMLSerializer.prototype.closeTag = function (element) { + return ''; + }; + HTMLSerializer.prototype.isVoid = function (element) { + return this.voidMap[element.nodeName] === true; + }; + HTMLSerializer.prototype.attributes = function (namedNodeMap) { + var buffer = ''; + for (var i = 0, l = namedNodeMap.length; i < l; i++) { + buffer += this.attr(namedNodeMap[i]); + } + return buffer; + }; + HTMLSerializer.prototype.escapeAttrValue = function (attrValue) { + return attrValue.replace(/"|&(?:#?[a-zA-Z0-9]+;)?/g, function (match) { + switch (match) { + case '&': + return '&'; + case '"': + return '"'; + default: + return match; + } + }); + }; + HTMLSerializer.prototype.attr = function (attr) { + if (!attr.specified) { + return ''; + } + if (attr.value) { + if (attr.name === 'href' || attr.name === 'src') { + return ' ' + attr.name + '="' + attr.value + '"'; + } + return ' ' + attr.name + '="' + this.escapeAttrValue(attr.value) + '"'; + } + return ' ' + attr.name; + }; + HTMLSerializer.prototype.escapeText = function (textNodeValue, escapeAll) { + return textNodeValue.replace(escapeAll ? REG_ESCAPE_ALL : REG_ESCAPE_PRESERVE_ENTITIES, function (match) { + switch (match) { + case '&': + return '&'; + case '<': + return '<'; + case '>': + return '>'; + default: + return match; + } + }); + }; + var metadataContentTags = { + style: true, + script: true, + template: true + }; + function isMetadataTag(elem) { + return !!elem && metadataContentTags[elem.nodeName.toLowerCase()]; + } + HTMLSerializer.prototype.text = function (text) { + if (isMetadataTag(text.parentNode)) { + return text.nodeValue; + } + return this.escapeText(text.nodeValue); + }; + HTMLSerializer.prototype.comment = function (comment) { + return ''; + }; + HTMLSerializer.prototype.serialize = function (node) { + var buffer = ''; + var next; + switch (node.nodeType) { + case 1: + buffer += this.openTag(node); + break; + case 3: + buffer += this.text(node); + break; + case 8: + buffer += this.comment(node); + break; + default: + break; + } + next = node.firstChild; + if (next) { + while (next) { + buffer += this.serialize(next); + next = next.nextSibling; + } + } else if (node.nodeType === 1 && node.textContent) { + buffer += this.escapeText(node.textContent, true); + } + if (node.nodeType === 1 && !this.isVoid(node)) { + buffer += this.closeTag(node); + } + return buffer; + }; + module.exports = HTMLSerializer; +}); +/*can-simple-dom@1.4.2#lib/void-map*/ +define('can-simple-dom@1.4.2#lib/void-map', function (require, exports, module) { + module.exports = { + AREA: true, + BASE: true, + BR: true, + COL: true, + COMMAND: true, + EMBED: true, + HR: true, + IMG: true, + INPUT: true, + KEYGEN: true, + LINK: true, + META: true, + PARAM: true, + SOURCE: true, + TRACK: true, + WBR: true + }; +}); +/*can-simple-dom@1.4.2#lib/dom*/ +define('can-simple-dom@1.4.2#lib/dom', [ + 'require', + 'exports', + 'module', + './document/node', + './document/element', + './document', + './event', + './html-parser', + './html-serializer', + './void-map' +], function (require, exports, module) { + var Node = require('./document/node').Node; + var Element = require('./document/element'); + var Document = require('./document'); + var Event = require('./event'); + var HTMLParser = require('./html-parser'); + var HTMLSerializer = require('./html-serializer'); + var voidMap = require('./void-map'); + function createDocument(serializer, parser) { + var doc = new Document(); + doc.__serializer = serializer; + doc.__parser = parser; + return doc; + } + exports.Node = Node; + exports.Element = Element; + exports.Document = Document; + exports.Event = Event; + exports.HTMLParser = HTMLParser; + exports.HTMLSerializer = HTMLSerializer; + exports.voidMap = voidMap; + exports.createDocument = createDocument; +}); +/*can-simple-dom@1.4.2#can-simple-dom*/ +define('can-simple-dom@1.4.2#can-simple-dom', [ + 'require', + 'exports', + 'module', + './lib/dom' +], function (require, exports, module) { + var SimpleDOM = require('./lib/dom'); + if (typeof window !== 'undefined') { + window.SimpleDOM = SimpleDOM; + } + exports = module.exports = SimpleDOM.Document; + exports.Node = SimpleDOM.Node; + exports.Element = SimpleDOM.Element; + exports.Document = SimpleDOM.Document; + exports.Event = SimpleDOM.Event; + exports.HTMLParser = SimpleDOM.HTMLParser; + exports.HTMLSerializer = SimpleDOM.HTMLSerializer; + exports.voidMap = SimpleDOM.voidMap; + exports.createDocument = SimpleDOM.createDocument; +}); +/*can-log@1.0.0#can-log*/ +define('can-log@1.0.0#can-log', function (require, exports, module) { + 'use strict'; + exports.warnTimeout = 5000; + exports.logLevel = 0; + exports.warn = function () { + var ll = this.logLevel; + if (ll < 2) { + if (typeof console !== 'undefined' && console.warn) { + this._logger('warn', Array.prototype.slice.call(arguments)); + } else if (typeof console !== 'undefined' && console.log) { + this._logger('log', Array.prototype.slice.call(arguments)); + } + } + }; + exports.log = function () { + var ll = this.logLevel; + if (ll < 1) { + if (typeof console !== 'undefined' && console.log) { + this._logger('log', Array.prototype.slice.call(arguments)); + } + } + }; + exports.error = function () { + var ll = this.logLevel; + if (ll < 1) { + if (typeof console !== 'undefined' && console.error) { + this._logger('error', Array.prototype.slice.call(arguments)); + } + } + }; + exports._logger = function (type, arr) { + try { + console[type].apply(console, arr); + } catch (e) { + console[type](arr); + } + }; +}); +/*can-log@1.0.0#dev/dev*/ +define('can-log@1.0.0#dev/dev', [ + 'require', + 'exports', + 'module', + '../can-log' +], function (require, exports, module) { + 'use strict'; + var canLog = require('../can-log'); + module.exports = { + warnTimeout: 5000, + logLevel: 0, + stringify: function (value) { + var flagUndefined = function flagUndefined(key, value) { + return value === undefined ? '/* void(undefined) */' : value; + }; + return JSON.stringify(value, flagUndefined, ' ').replace(/"\/\* void\(undefined\) \*\/"/g, 'undefined'); + }, + warn: function () { + }, + log: function () { + }, + error: function () { + }, + _logger: canLog._logger + }; +}); +/*can-attribute-encoder@1.1.1#can-attribute-encoder*/ +define('can-attribute-encoder@1.1.1#can-attribute-encoder', [ + 'require', + 'exports', + 'module', + 'can-namespace', + 'can-log/dev/dev' +], function (require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + var dev = require('can-log/dev/dev'); + function each(items, callback) { + for (var i = 0; i < items.length; i++) { + callback(items[i], i); + } + } + function makeMap(str) { + var obj = {}, items = str.split(','); + each(items, function (name) { + obj[name] = true; + }); + return obj; + } + var caseMattersAttributes = makeMap('allowReorder,attributeName,attributeType,autoReverse,baseFrequency,baseProfile,calcMode,clipPathUnits,contentScriptType,contentStyleType,diffuseConstant,edgeMode,externalResourcesRequired,filterRes,filterUnits,glyphRef,gradientTransform,gradientUnits,kernelMatrix,kernelUnitLength,keyPoints,keySplines,keyTimes,lengthAdjust,limitingConeAngle,markerHeight,markerUnits,markerWidth,maskContentUnits,maskUnits,patternContentUnits,patternTransform,patternUnits,pointsAtX,pointsAtY,pointsAtZ,preserveAlpha,preserveAspectRatio,primitiveUnits,repeatCount,repeatDur,requiredExtensions,requiredFeatures,specularConstant,specularExponent,spreadMethod,startOffset,stdDeviation,stitchTiles,surfaceScale,systemLanguage,tableValues,textLength,viewBox,viewTarget,xChannelSelector,yChannelSelector'); + function camelCaseToSpinalCase(match, lowerCaseChar, upperCaseChar) { + return lowerCaseChar + '-' + upperCaseChar.toLowerCase(); + } + function startsWith(allOfIt, startsWith) { + return allOfIt.indexOf(startsWith) === 0; + } + function endsWith(allOfIt, endsWith) { + return allOfIt.length - allOfIt.lastIndexOf(endsWith) === endsWith.length; + } + var regexes = { + leftParens: /\(/g, + rightParens: /\)/g, + leftBrace: /\{/g, + rightBrace: /\}/g, + camelCase: /([a-z]|^)([A-Z])/g, + forwardSlash: /\//g, + space: /\s/g, + uppercase: /[A-Z]/g, + uppercaseDelimiterThenChar: /:u:([a-z])/g, + caret: /\^/g, + dollar: /\$/g, + at: /@/g + }; + var delimiters = { + prependUppercase: ':u:', + replaceSpace: ':s:', + replaceForwardSlash: ':f:', + replaceLeftParens: ':lp:', + replaceRightParens: ':rp:', + replaceLeftBrace: ':lb:', + replaceRightBrace: ':rb:', + replaceCaret: ':c:', + replaceDollar: ':d:', + replaceAt: ':at:' + }; + var encoder = {}; + encoder.encode = function (name) { + var encoded = name; + if (!caseMattersAttributes[encoded] && encoded.match(regexes.camelCase)) { + if (startsWith(encoded, 'on:') || endsWith(encoded, ':to') || endsWith(encoded, ':from') || endsWith(encoded, ':bind') || endsWith(encoded, ':raw')) { + encoded = encoded.replace(regexes.uppercase, function (char) { + return delimiters.prependUppercase + char.toLowerCase(); + }); + } else if (startsWith(encoded, '(') || startsWith(encoded, '{')) { + encoded = encoded.replace(regexes.camelCase, camelCaseToSpinalCase); + } + } + encoded = encoded.replace(regexes.space, delimiters.replaceSpace).replace(regexes.forwardSlash, delimiters.replaceForwardSlash).replace(regexes.leftParens, delimiters.replaceLeftParens).replace(regexes.rightParens, delimiters.replaceRightParens).replace(regexes.leftBrace, delimiters.replaceLeftBrace).replace(regexes.rightBrace, delimiters.replaceRightBrace).replace(regexes.caret, delimiters.replaceCaret).replace(regexes.dollar, delimiters.replaceDollar).replace(regexes.at, delimiters.replaceAt); + return encoded; + }; + encoder.decode = function (name) { + var decoded = name; + if (!caseMattersAttributes[decoded] && regexes.uppercaseDelimiterThenChar.test(decoded)) { + if (startsWith(decoded, 'on:') || endsWith(decoded, ':to') || endsWith(decoded, ':from') || endsWith(decoded, ':bind') || endsWith(decoded, ':raw')) { + decoded = decoded.replace(regexes.uppercaseDelimiterThenChar, function (match, char) { + return char.toUpperCase(); + }); + } + } + decoded = decoded.replace(delimiters.replaceLeftParens, '(').replace(delimiters.replaceRightParens, ')').replace(delimiters.replaceLeftBrace, '{').replace(delimiters.replaceRightBrace, '}').replace(delimiters.replaceForwardSlash, '/').replace(delimiters.replaceSpace, ' ').replace(delimiters.replaceCaret, '^').replace(delimiters.replaceDollar, '$').replace(delimiters.replaceAt, '@'); + return decoded; + }; + if (namespace.encoder) { + throw new Error('You can\'t have two versions of can-attribute-encoder, check your dependencies'); + } else { + module.exports = namespace.encoder = encoder; + } +}); +/*can-view-parser@4.1.2#can-view-parser*/ +define('can-view-parser@4.1.2#can-view-parser', [ + 'require', + 'exports', + 'module', + 'can-namespace', + 'can-log/dev/dev', + 'can-attribute-encoder' +], function (require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'), dev = require('can-log/dev/dev'), encoder = require('can-attribute-encoder'); + function each(items, callback) { + for (var i = 0; i < items.length; i++) { + callback(items[i], i); + } + } + function makeMap(str) { + var obj = {}, items = str.split(','); + each(items, function (name) { + obj[name] = true; + }); + return obj; + } + function handleIntermediate(intermediate, handler) { + for (var i = 0, len = intermediate.length; i < len; i++) { + var item = intermediate[i]; + handler[item.tokenType].apply(handler, item.args); + } + return intermediate; + } + var alphaNumeric = 'A-Za-z0-9', alphaNumericHU = '-:_' + alphaNumeric, magicStart = '{{', endTag = new RegExp('^<\\/([' + alphaNumericHU + ']+)[^>]*>'), magicMatch = new RegExp('\\{\\{(![\\s\\S]*?!|[\\s\\S]*?)\\}\\}\\}?', 'g'), space = /\s/, alphaRegex = new RegExp('[' + alphaNumeric + ']'), attributeRegexp = new RegExp('[' + alphaNumericHU + ']+s*=s*("[^"]*"|\'[^\']*\')'); + var empty = makeMap('area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed'); + var caseMattersElements = makeMap('altGlyph,altGlyphDef,altGlyphItem,animateColor,animateMotion,animateTransform,clipPath,feBlend,feColorMatrix,feComponentTransfer,feComposite,feConvolveMatrix,feDiffuseLighting,feDisplacementMap,feDistantLight,feFlood,feFuncA,feFuncB,feFuncG,feFuncR,feGaussianBlur,feImage,feMerge,feMergeNode,feMorphology,feOffset,fePointLight,feSpecularLighting,feSpotLight,feTile,feTurbulence,foreignObject,glyphRef,linearGradient,radialGradient,textPath'); + var closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr'); + var special = makeMap('script'); + var tokenTypes = 'start,end,close,attrStart,attrEnd,attrValue,chars,comment,special,done'.split(','); + var startOppositesMap = { + '{': '}', + '(': ')' + }; + var fn = function () { + }; + var HTMLParser = function (html, handler, returnIntermediate) { + if (typeof html === 'object') { + return handleIntermediate(html, handler); + } + var intermediate = []; + handler = handler || {}; + if (returnIntermediate) { + each(tokenTypes, function (name) { + var callback = handler[name] || fn; + handler[name] = function () { + if (callback.apply(this, arguments) !== false) { + var end = arguments.length; + if (arguments[end - 1] === undefined) { + end = arguments.length - 1; + } + intermediate.push({ + tokenType: name, + args: [].slice.call(arguments, 0, end) + }); + } + }; + }); + } + function parseStartTag(tag, tagName, rest, unary) { + tagName = caseMattersElements[tagName] ? tagName : tagName.toLowerCase(); + if (closeSelf[tagName] && stack.last() === tagName) { + parseEndTag('', tagName); + } + unary = empty[tagName] || !!unary; + handler.start(tagName, unary, lineNo); + if (!unary) { + stack.push(tagName); + } + HTMLParser.parseAttrs(rest, handler, lineNo); + handler.end(tagName, unary, lineNo); + if (tagName === 'html') { + skipChars = true; + } + } + function parseEndTag(tag, tagName) { + var pos; + if (!tagName) { + pos = 0; + } else { + tagName = caseMattersElements[tagName] ? tagName : tagName.toLowerCase(); + for (pos = stack.length - 1; pos >= 0; pos--) { + if (stack[pos] === tagName) { + break; + } + } + } + if (pos >= 0) { + for (var i = stack.length - 1; i >= pos; i--) { + if (handler.close) { + handler.close(stack[i], lineNo); + } + } + stack.length = pos; + if (tagName === 'body') { + skipChars = true; + } + } + } + function parseMustache(mustache, inside) { + if (handler.special) { + handler.special(inside, lineNo); + } + } + var callChars = function () { + if (charsText && !skipChars) { + if (handler.chars) { + handler.chars(charsText, lineNo); + } + } + skipChars = false; + charsText = ''; + }; + var index, chars, skipChars, match, lineNo, stack = [], last = html, charsText = ''; + stack.last = function () { + return this[this.length - 1]; + }; + while (html) { + chars = true; + if (!stack.last() || !special[stack.last()]) { + if (html.indexOf(''); + if (index >= 0) { + callChars(); + if (handler.comment) { + handler.comment(html.substring(4, index), lineNo); + } + html = html.substring(index + 3); + chars = false; + } + } else if (html.indexOf(']*>'), function (all, text) { + text = text.replace(/|/g, '$1$2'); + if (handler.chars) { + handler.chars(text, lineNo); + } + return ''; + }); + parseEndTag('', stack.last()); + } + if (html === last) { + throw new Error('Parse Error: ' + html); + } + last = html; + } + callChars(); + parseEndTag(); + handler.done(lineNo); + return intermediate; + }; + var callAttrStart = function (state, curIndex, handler, rest, lineNo) { + var attrName = rest.substring(typeof state.nameStart === 'number' ? state.nameStart : curIndex, curIndex), newAttrName = encoder.encode(attrName); + state.attrStart = newAttrName; + handler.attrStart(state.attrStart, lineNo); + state.inName = false; + }; + var callAttrEnd = function (state, curIndex, handler, rest, lineNo) { + if (state.valueStart !== undefined && state.valueStart < curIndex) { + var val = rest.substring(state.valueStart, curIndex); + handler.attrValue(val, lineNo); + } + handler.attrEnd(state.attrStart, lineNo); + state.attrStart = undefined; + state.valueStart = undefined; + state.inValue = false; + state.inName = false; + state.lookingForEq = false; + state.inQuote = false; + state.lookingForName = true; + }; + var findBreak = function (str, magicStart) { + var magicLength = magicStart.length; + for (var i = 0, len = str.length; i < len; i++) { + if (str[i] === '<' || str.substr(i, magicLength) === magicStart) { + return i; + } + } + return -1; + }; + HTMLParser.parseAttrs = function (rest, handler, lineNo) { + if (!rest) { + return; + } + var i = 0; + var curIndex; + var state = { + inName: false, + nameStart: undefined, + inValue: false, + valueStart: undefined, + inQuote: false, + attrStart: undefined, + lookingForName: true, + lookingForValue: false, + lookingForEq: false + }; + while (i < rest.length) { + curIndex = i; + var cur = rest.charAt(i); + i++; + if (magicStart === rest.substr(curIndex, magicStart.length)) { + if (state.inValue && curIndex > state.valueStart) { + handler.attrValue(rest.substring(state.valueStart, curIndex), lineNo); + } else if (state.inName && state.nameStart < curIndex) { + callAttrStart(state, curIndex, handler, rest, lineNo); + callAttrEnd(state, curIndex, handler, rest, lineNo); + } else if (state.lookingForValue) { + state.inValue = true; + } else if (state.lookingForEq && state.attrStart) { + callAttrEnd(state, curIndex, handler, rest, lineNo); + } + magicMatch.lastIndex = curIndex; + var match = magicMatch.exec(rest); + if (match) { + handler.special(match[1], lineNo); + i = curIndex + match[0].length; + if (state.inValue) { + state.valueStart = curIndex + match[0].length; + } + } + } else if (state.inValue) { + if (state.inQuote) { + if (cur === state.inQuote) { + callAttrEnd(state, curIndex, handler, rest, lineNo); + } + } else if (space.test(cur)) { + callAttrEnd(state, curIndex, handler, rest, lineNo); + } + } else if (cur === '=' && (state.lookingForEq || state.lookingForName || state.inName)) { + if (!state.attrStart) { + callAttrStart(state, curIndex, handler, rest, lineNo); + } + state.lookingForValue = true; + state.lookingForEq = false; + state.lookingForName = false; + } else if (state.inName) { + var started = rest[state.nameStart], otherStart, otherOpposite; + if (startOppositesMap[started] === cur) { + otherStart = started === '{' ? '(' : '{'; + otherOpposite = startOppositesMap[otherStart]; + if (rest[curIndex + 1] === otherOpposite) { + callAttrStart(state, curIndex + 2, handler, rest, lineNo); + i++; + } else { + callAttrStart(state, curIndex + 1, handler, rest, lineNo); + } + state.lookingForEq = true; + } else if (space.test(cur) && started !== '{' && started !== '(') { + callAttrStart(state, curIndex, handler, rest, lineNo); + state.lookingForEq = true; + } + } else if (state.lookingForName) { + if (!space.test(cur)) { + if (state.attrStart) { + callAttrEnd(state, curIndex, handler, rest, lineNo); + } + state.nameStart = curIndex; + state.inName = true; + } + } else if (state.lookingForValue) { + if (!space.test(cur)) { + state.lookingForValue = false; + state.inValue = true; + if (cur === '\'' || cur === '"') { + state.inQuote = cur; + state.valueStart = curIndex + 1; + } else { + state.valueStart = curIndex; + } + } else if (i === rest.length) { + callAttrEnd(state, curIndex, handler, rest, lineNo); + } + } + } + if (state.inName) { + callAttrStart(state, curIndex + 1, handler, rest, lineNo); + callAttrEnd(state, curIndex + 1, handler, rest, lineNo); + } else if (state.lookingForEq || state.lookingForValue || state.inValue) { + callAttrEnd(state, curIndex + 1, handler, rest, lineNo); + } + magicMatch.lastIndex = 0; + }; + HTMLParser.searchStartTag = function (html) { + var closingIndex = html.indexOf('>'); + var attributeRange = attributeRegexp.exec(html.substring(1)); + var afterAttributeOffset = 1; + while (attributeRange && closingIndex >= afterAttributeOffset + attributeRange.index) { + afterAttributeOffset += attributeRange.index + attributeRange[0].length; + while (closingIndex < afterAttributeOffset) { + closingIndex += html.substring(closingIndex + 1).indexOf('>') + 1; + } + attributeRange = attributeRegexp.exec(html.substring(afterAttributeOffset)); + } + if (closingIndex === -1 || !alphaRegex.test(html[1])) { + return null; + } + var tagName, tagContent, match, rest = '', unary = ''; + var startTag = html.substring(0, closingIndex + 1); + var isUnary = startTag[startTag.length - 2] === '/'; + var spaceIndex = startTag.search(space); + if (isUnary) { + unary = '/'; + tagContent = startTag.substring(1, startTag.length - 2).trim(); + } else { + tagContent = startTag.substring(1, startTag.length - 1).trim(); + } + if (spaceIndex === -1) { + tagName = tagContent; + } else { + spaceIndex--; + tagName = tagContent.substring(0, spaceIndex); + rest = tagContent.substring(spaceIndex); + } + match = [ + startTag, + tagName, + rest, + unary + ]; + return { + match: match, + html: html.substring(startTag.length) + }; + }; + module.exports = namespace.HTMLParser = HTMLParser; +}); +/*can-vdom@4.4.0#make-parser/make-parser*/ +define('can-vdom@4.4.0#make-parser/make-parser', [ + 'require', + 'exports', + 'module', + 'can-view-parser', + 'can-simple-dom' +], function (require, exports, module) { + 'use strict'; + var canParser = require('can-view-parser'); + var simpleDOM = require('can-simple-dom'); + module.exports = function (document) { + return new simpleDOM.HTMLParser(function (string) { + var tokens = []; + var currentTag, currentAttr; + canParser(string, { + start: function (tagName, unary) { + currentTag = { + type: 'StartTag', + attributes: [], + tagName: tagName + }; + }, + end: function (tagName, unary) { + tokens.push(currentTag); + currentTag = undefined; + }, + close: function (tagName) { + tokens.push({ + type: 'EndTag', + tagName: tagName + }); + }, + attrStart: function (attrName) { + currentAttr = [ + attrName, + '' + ]; + currentTag.attributes.push(currentAttr); + }, + attrEnd: function (attrName) { + }, + attrValue: function (value) { + currentAttr[1] += value; + }, + chars: function (value) { + tokens.push({ + type: 'Chars', + chars: value + }); + }, + comment: function (value) { + tokens.push({ + type: 'Comment', + chars: value + }); + }, + special: function (value) { + }, + done: function () { + } + }); + return tokens; + }, document, simpleDOM.voidMap); + }; +}); +/*can-vdom@4.4.0#make-document/make-document*/ +define('can-vdom@4.4.0#make-document/make-document', [ + 'require', + 'exports', + 'module', + 'can-simple-dom', + '../make-parser/make-parser' +], function (require, exports, module) { + 'use strict'; + var simpleDOM = require('can-simple-dom'); + var makeParser = require('../make-parser/make-parser'); + function CanSimpleDocument() { + simpleDOM.Document.apply(this, arguments); + var serializer = new simpleDOM.HTMLSerializer(simpleDOM.voidMap); + var parser = makeParser(this); + this.__addSerializerAndParser(serializer, parser); + } + CanSimpleDocument.prototype = new simpleDOM.Document(); + CanSimpleDocument.prototype.constructor = CanSimpleDocument; + module.exports = function () { + return new CanSimpleDocument(); + }; +}); +/*can-dom-mutate@1.3.5#-util*/ +define('can-dom-mutate@1.3.5#-util', [ + 'require', + 'exports', + 'module', + 'can-globals/document/document' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var getDocument = require('can-globals/document/document'); + function eliminate(array, item) { + var index = array.indexOf(item); + if (index >= 0) { + array.splice(index, 1); + } + } + function addToSet(items, set) { + for (var i = 0, length = items.length; i < length; i++) { + set.add(items[i]); + } + } + function contains(parent, child) { + if (parent.contains) { + return parent.contains(child); + } + if (parent.nodeType === Node.DOCUMENT_NODE && parent.documentElement) { + return contains(parent.documentElement, child); + } else { + child = child.parentNode; + if (child === parent) { + return true; + } + return false; + } + } + function isInDocument(node) { + var root = getDocument(); + if (root === node) { + return true; + } + return contains(root, node); + } + function isDocumentElement(node) { + return getDocument().documentElement === node; + } + function isFragment(node) { + return !!(node && node.nodeType === 11); + } + function isElementNode(node) { + return !!(node && node.nodeType === 1); + } + function getChildren(parentNode) { + var nodes = []; + var node = parentNode.firstChild; + while (node) { + nodes.push(node); + node = node.nextSibling; + } + return nodes; + } + function getParents(node) { + var nodes; + if (isFragment(node)) { + nodes = getChildren(node); + } else { + nodes = [node]; + } + return nodes; + } + function getNodesLegacyB(node) { + var skip, tmp; + var depth = 0; + var items = isFragment(node) ? [] : [node]; + if (node.firstChild == null) { + return items; + } + do { + if (!skip && (tmp = node.firstChild)) { + depth++; + items.push(tmp); + } else if (tmp = node.nextSibling) { + skip = false; + items.push(tmp); + } else { + tmp = node.parentNode; + depth--; + skip = true; + } + node = tmp; + } while (depth > 0); + return items; + } + function treeWalkerFilterFunction() { + return NodeFilter.FILTER_ACCEPT; + } + var treeWalkerFilter = treeWalkerFilterFunction; + treeWalkerFilter.acceptNode = treeWalkerFilterFunction; + function getNodesWithTreeWalker(rootNode) { + var result = isFragment(rootNode) ? [] : [rootNode]; + var walker = isElementNode(rootNode) && getDocument().createTreeWalker(rootNode, NodeFilter.SHOW_TEXT | NodeFilter.SHOW_ELEMENT, treeWalkerFilter, false); + var node; + while (node = walker && walker.nextNode()) { + result.push(node); + } + return result; + } + function getAllNodes(node) { + if (getDocument().createTreeWalker !== undefined) { + return getNodesWithTreeWalker(node); + } else { + return getNodesLegacyB(node); + } + } + function subscription(fn) { + return function _subscription() { + var disposal = fn.apply(this, arguments); + var isDisposed = false; + return function _disposal() { + if (isDisposed) { + var fnName = fn.name || fn.displayName || 'an anonymous function'; + var message = 'Disposal function returned by ' + fnName + ' called more than once.'; + throw new Error(message); + } + disposal.apply(this, arguments); + isDisposed = true; + }; + }; + } + module.exports = { + eliminate: eliminate, + isInDocument: isInDocument, + getDocument: getDocument, + isDocumentElement: isDocumentElement, + isFragment: isFragment, + getParents: getParents, + getAllNodes: getAllNodes, + getChildren: getChildren, + subscription: subscription, + addToSet: addToSet + }; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-dom-mutate@1.3.5#can-dom-mutate*/ +define('can-dom-mutate@1.3.5#can-dom-mutate', [ + 'require', + 'exports', + 'module', + 'can-globals', + 'can-globals/global/global', + 'can-globals/mutation-observer/mutation-observer', + 'can-namespace', + 'can-globals/document/document', + 'can-reflect', + './-util' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var globals = require('can-globals'); + var getRoot = require('can-globals/global/global'); + var getMutationObserver = require('can-globals/mutation-observer/mutation-observer'); + var namespace = require('can-namespace'); + var DOCUMENT = require('can-globals/document/document'); + var canReflect = require('can-reflect'); + var util = require('./-util'); + var eliminate = util.eliminate; + var subscription = util.subscription; + var isDocumentElement = util.isDocumentElement; + var getAllNodes = util.getAllNodes; + var slice = Array.prototype.slice; + var domMutate, dispatchInsertion, dispatchRemoval; + var dataStore = new WeakMap(); + function getRelatedData(node, key) { + var data = dataStore.get(node); + if (data) { + return data[key]; + } + } + function setRelatedData(node, key, targetListenersMap) { + var data = dataStore.get(node); + if (!data) { + data = {}; + dataStore.set(node, data); + } + data[key] = targetListenersMap; + } + function deleteRelatedData(node, key) { + var data = dataStore.get(node); + return delete data[key]; + } + function toMutationEvents(nodes) { + var events = []; + for (var i = 0; i < nodes.length; i++) { + events.push({ target: nodes[i] }); + } + return events; + } + function batch(processBatchItems) { + return function batchAdd(items, callback) { + processBatchItems(items); + if (callback) { + callback(); + } + }; + } + function getDocumentListeners(target, key) { + var doc = DOCUMENT(); + var data = getRelatedData(doc, key); + if (data) { + return data.listeners; + } + } + function getTargetListeners(target, key) { + var doc = DOCUMENT(); + var targetListenersMap = getRelatedData(doc, key); + if (!targetListenersMap) { + return; + } + return targetListenersMap.get(target); + } + function addTargetListener(target, key, listener) { + var doc = DOCUMENT(); + var targetListenersMap = getRelatedData(doc, key); + if (!targetListenersMap) { + targetListenersMap = new Map(); + setRelatedData(doc, key, targetListenersMap); + } + var targetListeners = targetListenersMap.get(target); + if (!targetListeners) { + targetListeners = []; + targetListenersMap.set(target, targetListeners); + } + targetListeners.push(listener); + } + function removeTargetListener(target, key, listener) { + var doc = DOCUMENT(); + var targetListenersMap = getRelatedData(doc, key); + if (!targetListenersMap) { + return; + } + var targetListeners = targetListenersMap.get(target); + if (!targetListeners) { + return; + } + eliminate(targetListeners, listener); + if (targetListeners.length === 0) { + targetListenersMap['delete'](target); + if (targetListenersMap.size === 0) { + deleteRelatedData(doc, key); + } + } + } + function fire(callbacks, arg) { + var safeCallbacks = slice.call(callbacks, 0); + var safeCallbackCount = safeCallbacks.length; + for (var i = 0; i < safeCallbackCount; i++) { + safeCallbacks[i](arg); + } + } + function dispatch(listenerKey, documentDataKey) { + return function dispatchEvents(events) { + for (var e = 0; e < events.length; e++) { + var event = events[e]; + var target = event.target; + var targetListeners = getTargetListeners(target, listenerKey); + if (targetListeners) { + fire(targetListeners, event); + } + if (!documentDataKey) { + continue; + } + var documentListeners = getDocumentListeners(target, documentDataKey); + if (documentListeners) { + fire(documentListeners, event); + } + } + }; + } + var count = 0; + function observeMutations(target, observerKey, config, handler) { + var observerData = getRelatedData(target, observerKey); + if (!observerData) { + observerData = { observingCount: 0 }; + setRelatedData(target, observerKey, observerData); + } + var setupObserver = function () { + if (observerData.observer) { + observerData.observer.disconnect(); + observerData.observer = null; + } + var MutationObserver = getMutationObserver(); + if (MutationObserver) { + var Node = getRoot().Node; + var isRealNode = !!(Node && target instanceof Node); + if (isRealNode) { + var targetObserver = new MutationObserver(handler); + targetObserver.id = count++; + targetObserver.observe(target, config); + observerData.observer = targetObserver; + } + } + }; + if (observerData.observingCount === 0) { + globals.onKeyValue('MutationObserver', setupObserver); + setupObserver(); + } + observerData.observingCount++; + return function stopObservingMutations() { + var observerData = getRelatedData(target, observerKey); + if (observerData) { + observerData.observingCount--; + if (observerData.observingCount <= 0) { + if (observerData.observer) { + observerData.observer.disconnect(); + } + deleteRelatedData(target, observerKey); + globals.offKeyValue('MutationObserver', setupObserver); + } + } + }; + } + function handleTreeMutations(mutations) { + if (typeof Set === 'undefined') { + return; + } + var mutationCount = mutations.length; + var added = new Set(), removed = new Set(); + for (var m = 0; m < mutationCount; m++) { + var mutation = mutations[m]; + var addedCount = mutation.addedNodes.length; + for (var a = 0; a < addedCount; a++) { + util.addToSet(getAllNodes(mutation.addedNodes[a]), added); + } + var removedCount = mutation.removedNodes.length; + for (var r = 0; r < removedCount; r++) { + util.addToSet(getAllNodes(mutation.removedNodes[r]), removed); + } + } + dispatchRemoval(toMutationEvents(canReflect.toArray(removed))); + dispatchInsertion(toMutationEvents(canReflect.toArray(added))); + } + function handleAttributeMutations(mutations) { + var mutationCount = mutations.length; + for (var m = 0; m < mutationCount; m++) { + var mutation = mutations[m]; + if (mutation.type === 'attributes') { + var node = mutation.target; + var attributeName = mutation.attributeName; + var oldValue = mutation.oldValue; + domMutate.dispatchNodeAttributeChange(node, attributeName, oldValue); + } + } + } + var treeMutationConfig = { + subtree: true, + childList: true + }; + var attributeMutationConfig = { + attributes: true, + attributeOldValue: true + }; + function addNodeListener(listenerKey, observerKey, isAttributes) { + return subscription(function _addNodeListener(target, listener) { + if (target.nodeType === 11) { + return Function.prototype; + } + var stopObserving; + if (isAttributes) { + stopObserving = observeMutations(target, observerKey, attributeMutationConfig, handleAttributeMutations); + } else { + stopObserving = observeMutations(DOCUMENT(), observerKey, treeMutationConfig, handleTreeMutations); + } + addTargetListener(target, listenerKey, listener); + return function removeNodeListener() { + stopObserving(); + removeTargetListener(target, listenerKey, listener); + }; + }); + } + function addGlobalListener(globalDataKey, addNodeListener) { + return subscription(function addGlobalGroupListener(documentElement, listener) { + if (!isDocumentElement(documentElement)) { + throw new Error('Global mutation listeners must pass a documentElement'); + } + var doc = DOCUMENT(); + var documentData = getRelatedData(doc, globalDataKey); + if (!documentData) { + documentData = { listeners: [] }; + setRelatedData(doc, globalDataKey, documentData); + } + var listeners = documentData.listeners; + if (listeners.length === 0) { + documentData.removeListener = addNodeListener(doc, function () { + }); + } + listeners.push(listener); + return function removeGlobalGroupListener() { + var documentData = getRelatedData(doc, globalDataKey); + if (!documentData) { + return; + } + var listeners = documentData.listeners; + eliminate(listeners, listener); + if (listeners.length === 0) { + documentData.removeListener(); + deleteRelatedData(doc, globalDataKey); + } + }; + }); + } + var domMutationPrefix = 'domMutation'; + var insertionDataKey = domMutationPrefix + 'InsertionData'; + var removalDataKey = domMutationPrefix + 'RemovalData'; + var attributeChangeDataKey = domMutationPrefix + 'AttributeChangeData'; + var documentInsertionDataKey = domMutationPrefix + 'DocumentInsertionData'; + var documentRemovalDataKey = domMutationPrefix + 'DocumentRemovalData'; + var documentAttributeChangeDataKey = domMutationPrefix + 'DocumentAttributeChangeData'; + var treeDataKey = domMutationPrefix + 'TreeData'; + var attributeDataKey = domMutationPrefix + 'AttributeData'; + dispatchInsertion = batch(dispatch(insertionDataKey, documentInsertionDataKey)); + dispatchRemoval = batch(dispatch(removalDataKey, documentRemovalDataKey)); + var dispatchAttributeChange = batch(dispatch(attributeChangeDataKey, documentAttributeChangeDataKey)); + var addNodeInsertionListener = addNodeListener(insertionDataKey, treeDataKey); + var addNodeRemovalListener = addNodeListener(removalDataKey, treeDataKey); + var addNodeAttributeChangeListener = addNodeListener(attributeChangeDataKey, attributeDataKey, true); + var addInsertionListener = addGlobalListener(documentInsertionDataKey, addNodeInsertionListener); + var addRemovalListener = addGlobalListener(documentRemovalDataKey, addNodeRemovalListener); + var addAttributeChangeListener = addGlobalListener(documentAttributeChangeDataKey, addNodeAttributeChangeListener); + domMutate = { + dispatchNodeInsertion: function (node, callback) { + var nodes = new Set(); + util.addToSet(getAllNodes(node), nodes); + var events = toMutationEvents(canReflect.toArray(nodes)); + dispatchInsertion(events, callback); + }, + dispatchNodeRemoval: function (node, callback) { + var nodes = new Set(); + util.addToSet(getAllNodes(node), nodes); + var events = toMutationEvents(canReflect.toArray(nodes)); + dispatchRemoval(events, callback); + }, + dispatchNodeAttributeChange: function (target, attributeName, oldValue, callback) { + dispatchAttributeChange([{ + target: target, + attributeName: attributeName, + oldValue: oldValue + }], callback); + }, + onNodeInsertion: addNodeInsertionListener, + onNodeRemoval: addNodeRemovalListener, + onNodeAttributeChange: addNodeAttributeChangeListener, + onRemoval: addRemovalListener, + onInsertion: addInsertionListener, + onAttributeChange: addAttributeChangeListener + }; + module.exports = namespace.domMutate = domMutate; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-dom-mutate@1.3.5#node*/ +define('can-dom-mutate@1.3.5#node', [ + 'require', + 'exports', + 'module', + 'can-globals', + 'can-namespace', + './can-dom-mutate', + './-util' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var globals = require('can-globals'); + var namespace = require('can-namespace'); + var domMutate = require('./can-dom-mutate'); + var util = require('./-util'); + var isInDocument = util.isInDocument; + var getParents = util.getParents; + var synthetic = { + dispatchNodeInsertion: function (container, node) { + if (isInDocument(node)) { + domMutate.dispatchNodeInsertion(node); + } + }, + dispatchNodeRemoval: function (container, node) { + if (isInDocument(container) && !isInDocument(node)) { + domMutate.dispatchNodeRemoval(node); + } + } + }; + var compat = { + replaceChild: function (newChild, oldChild) { + var newChildren = getParents(newChild); + var result = this.replaceChild(newChild, oldChild); + synthetic.dispatchNodeRemoval(this, oldChild); + for (var i = 0; i < newChildren.length; i++) { + synthetic.dispatchNodeInsertion(this, newChildren[i]); + } + return result; + }, + setAttribute: function (name, value) { + var oldAttributeValue = this.getAttribute(name); + var result = this.setAttribute(name, value); + var newAttributeValue = this.getAttribute(name); + if (oldAttributeValue !== newAttributeValue) { + domMutate.dispatchNodeAttributeChange(this, name, oldAttributeValue); + } + return result; + }, + removeAttribute: function (name) { + var oldAttributeValue = this.getAttribute(name); + var result = this.removeAttribute(name); + if (oldAttributeValue) { + domMutate.dispatchNodeAttributeChange(this, name, oldAttributeValue); + } + return result; + } + }; + var compatData = [ + [ + 'appendChild', + 'Insertion' + ], + [ + 'insertBefore', + 'Insertion' + ], + [ + 'removeChild', + 'Removal' + ] + ]; + compatData.forEach(function (pair) { + var nodeMethod = pair[0]; + var dispatchMethod = 'dispatchNode' + pair[1]; + compat[nodeMethod] = function (node) { + var nodes = getParents(node); + var result = this[nodeMethod].apply(this, arguments); + for (var i = 0; i < nodes.length; i++) { + synthetic[dispatchMethod](this, nodes[i]); + } + return result; + }; + }); + var normal = {}; + var nodeMethods = [ + 'appendChild', + 'insertBefore', + 'removeChild', + 'replaceChild', + 'setAttribute', + 'removeAttribute' + ]; + nodeMethods.forEach(function (methodName) { + normal[methodName] = function () { + return this[methodName].apply(this, arguments); + }; + }); + var mutate = {}; + function setMutateStrategy(observer) { + var strategy = observer ? normal : compat; + for (var key in strategy) { + mutate[key] = strategy[key]; + } + } + var mutationObserverKey = 'MutationObserver'; + setMutateStrategy(globals.getKeyValue(mutationObserverKey)); + globals.onKeyValue(mutationObserverKey, setMutateStrategy); + module.exports = namespace.domMutateNode = domMutate.node = mutate; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-component@4.4.9#test/helpers*/ +define('can-component@4.4.9#test/helpers', [ + 'require', + 'exports', + 'module', + 'can-globals/mutation-observer/mutation-observer', + 'can-globals', + 'can-globals/document/document', + 'can-vdom/make-document/make-document', + 'can-dom-mutate', + 'can-dom-mutate/node', + 'can-globals' +], function (require, exports, module) { + (function (global, require, exports, module) { + var MUTATION_OBSERVER = require('can-globals/mutation-observer/mutation-observer'); + var globals = require('can-globals'); + var DOCUMENT = require('can-globals/document/document'); + var makeDocument = require('can-vdom/make-document/make-document'); + var domMutate = require('can-dom-mutate'); + var domMutateNode = require('can-dom-mutate/node'); + var globals = require('can-globals'); + var helpers = { + runTasks: function (tasks) { + var nextTask = function () { + var next = tasks.shift(); + next(); + if (tasks.length) { + setTimeout(nextTask, 100); + } else { + start(); + } + }; + setTimeout(nextTask, 100); + }, + makeTest: function (name, doc, mutObs, test, qUnitTest) { + var DOC = DOCUMENT(); + QUnit.module(name, { + setup: function () { + DOCUMENT(doc); + if (!mutObs) { + globals.setKeyValue('MutationObserver', mutObs); + } + if (doc) { + this.document = doc; + this.fixture = doc.createElement('div'); + doc.body.appendChild(this.fixture); + } else { + this.fixture = doc.getElementById('qunit-fixture'); + } + }, + teardown: function () { + doc.body.removeChild(this.fixture); + stop(); + setTimeout(function () { + start(); + DOCUMENT(DOC); + globals.deleteKeyValue('MutationObserver'); + }, 100); + } + }); + test(doc, qUnitTest); + }, + makeTests: function (name, test) { + helpers.makeTest(name + ' - dom', document, MUTATION_OBSERVER(), test, QUnit.test); + helpers.makeTest(name + ' - vdom', makeDocument(), null, test, function () { + }); + }, + afterMutation: function (cb) { + var doc = globals.getKeyValue('document'); + var div = doc.createElement('div'); + var insertionDisposal = domMutate.onNodeInsertion(div, function () { + insertionDisposal(); + doc.body.removeChild(div); + setTimeout(cb, 5); + }); + setTimeout(function () { + domMutateNode.appendChild.call(doc.body, div); + }, 10); + } + }; + module.exports = helpers; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-string@1.0.0#can-string*/ +define('can-string@1.0.0#can-string', function (require, exports, module) { + 'use strict'; + var strUndHash = /_|-/, strColons = /\=\=/, strWords = /([A-Z]+)([A-Z][a-z])/g, strLowUp = /([a-z\d])([A-Z])/g, strDash = /([a-z\d])([A-Z])/g, strQuote = /"/g, strSingleQuote = /'/g, strHyphenMatch = /-+(.)?/g, strCamelMatch = /[a-z][A-Z]/g, convertBadValues = function (content) { + var isInvalid = content === null || content === undefined || isNaN(content) && '' + content === 'NaN'; + return '' + (isInvalid ? '' : content); + }; + var string = { + esc: function (content) { + return convertBadValues(content).replace(/&/g, '&').replace(//g, '>').replace(strQuote, '"').replace(strSingleQuote, '''); + }, + capitalize: function (s) { + return s.charAt(0).toUpperCase() + s.slice(1); + }, + camelize: function (str) { + return convertBadValues(str).replace(strHyphenMatch, function (match, chr) { + return chr ? chr.toUpperCase() : ''; + }); + }, + hyphenate: function (str) { + return convertBadValues(str).replace(strCamelMatch, function (str) { + return str.charAt(0) + '-' + str.charAt(1).toLowerCase(); + }); + }, + underscore: function (s) { + return s.replace(strColons, '/').replace(strWords, '$1_$2').replace(strLowUp, '$1_$2').replace(strDash, '_').toLowerCase(); + }, + undHash: strUndHash + }; + module.exports = string; +}); +/*can-construct@3.5.3#can-construct*/ +define('can-construct@3.5.3#can-construct', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-log/dev/dev', + 'can-namespace' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var dev = require('can-log/dev/dev'); + var namespace = require('can-namespace'); + var initializing = 0; + var Construct = function () { + if (arguments.length) { + return Construct.extend.apply(Construct, arguments); + } + }; + var canGetDescriptor; + try { + Object.getOwnPropertyDescriptor({}); + canGetDescriptor = true; + } catch (e) { + canGetDescriptor = false; + } + var getDescriptor = function (newProps, name) { + var descriptor = Object.getOwnPropertyDescriptor(newProps, name); + if (descriptor && (descriptor.get || descriptor.set)) { + return descriptor; + } + return null; + }, inheritGetterSetter = function (newProps, oldProps, addTo) { + addTo = addTo || newProps; + var descriptor; + for (var name in newProps) { + if (descriptor = getDescriptor(newProps, name)) { + this._defineProperty(addTo, oldProps, name, descriptor); + } else { + Construct._overwrite(addTo, oldProps, name, newProps[name]); + } + } + }, simpleInherit = function (newProps, oldProps, addTo) { + addTo = addTo || newProps; + for (var name in newProps) { + Construct._overwrite(addTo, oldProps, name, newProps[name]); + } + }, defineNonEnumerable = function (obj, prop, value) { + Object.defineProperty(obj, prop, { + configurable: true, + writable: true, + enumerable: false, + value: value + }); + }; + canReflect.assignMap(Construct, { + constructorExtends: true, + newInstance: function () { + var inst = this.instance(), args; + if (inst.setup) { + Object.defineProperty(inst, '__inSetup', { + configurable: true, + enumerable: false, + value: true, + writable: true + }); + args = inst.setup.apply(inst, arguments); + if (args instanceof Construct.ReturnValue) { + return args.value; + } + inst.__inSetup = false; + } + if (inst.init) { + inst.init.apply(inst, args || arguments); + } + return inst; + }, + _inherit: canGetDescriptor ? inheritGetterSetter : simpleInherit, + _defineProperty: function (what, oldProps, propName, descriptor) { + Object.defineProperty(what, propName, descriptor); + }, + _overwrite: function (what, oldProps, propName, val) { + Object.defineProperty(what, propName, { + value: val, + configurable: true, + enumerable: true, + writable: true + }); + }, + setup: function (base) { + var defaults = canReflect.assignDeepMap({}, base.defaults); + this.defaults = canReflect.assignDeepMap(defaults, this.defaults); + }, + instance: function () { + initializing = 1; + var inst = new this(); + initializing = 0; + return inst; + }, + extend: function (name, staticProperties, instanceProperties) { + var shortName = name, klass = staticProperties, proto = instanceProperties; + if (typeof shortName !== 'string') { + proto = klass; + klass = shortName; + shortName = null; + } + if (!proto) { + proto = klass; + klass = null; + } + proto = proto || {}; + var _super_class = this, _super = this.prototype, Constructor, prototype; + prototype = this.instance(); + Construct._inherit(proto, _super, prototype); + if (shortName) { + } else if (klass && klass.shortName) { + shortName = klass.shortName; + } else if (this.shortName) { + shortName = this.shortName; + } + function init() { + if (!initializing) { + return (!this || this.constructor !== Constructor) && arguments.length && Constructor.constructorExtends ? Constructor.extend.apply(Constructor, arguments) : Constructor.newInstance.apply(Constructor, arguments); + } + } + Constructor = typeof namedCtor === 'function' ? namedCtor(constructorName, init) : function () { + return init.apply(this, arguments); + }; + for (var propName in _super_class) { + if (_super_class.hasOwnProperty(propName)) { + Constructor[propName] = _super_class[propName]; + } + } + Construct._inherit(klass, _super_class, Constructor); + canReflect.assignMap(Constructor, { + constructor: Constructor, + prototype: prototype + }); + if (shortName !== undefined) { + if (Object.getOwnPropertyDescriptor) { + var desc = Object.getOwnPropertyDescriptor(Constructor, 'name'); + if (!desc || desc.configurable) { + Object.defineProperty(Constructor, 'name', { + writable: true, + value: shortName, + configurable: true + }); + } + } + Constructor.shortName = shortName; + } + defineNonEnumerable(Constructor.prototype, 'constructor', Constructor); + var t = [_super_class].concat(Array.prototype.slice.call(arguments)), args = Constructor.setup.apply(Constructor, t); + if (Constructor.init) { + Constructor.init.apply(Constructor, args || t); + } + return Constructor; + }, + ReturnValue: function (value) { + this.value = value; + } + }); + defineNonEnumerable(Construct.prototype, 'setup', function () { + }); + defineNonEnumerable(Construct.prototype, 'init', function () { + }); + module.exports = namespace.Construct = Construct; +}); +/*can-queues@1.2.1#queue-state*/ +define('can-queues@1.2.1#queue-state', function (require, exports, module) { + 'use strict'; + module.exports = { lastTask: null }; +}); +/*can-assign@1.3.1#can-assign*/ +define('can-assign@1.3.1#can-assign', [ + 'require', + 'exports', + 'module', + 'can-namespace' +], function (require, exports, module) { + var namespace = require('can-namespace'); + module.exports = namespace.assign = function (d, s) { + for (var prop in s) { + var desc = Object.getOwnPropertyDescriptor(d, prop); + if (!desc || desc.writable !== false) { + d[prop] = s[prop]; + } + } + return d; + }; +}); +/*can-queues@1.2.1#queue*/ +define('can-queues@1.2.1#queue', [ + 'require', + 'exports', + 'module', + './queue-state', + 'can-log/dev/dev', + 'can-assign' +], function (require, exports, module) { + 'use strict'; + var queueState = require('./queue-state'); + var canDev = require('can-log/dev/dev'); + var assign = require('can-assign'); + function noOperation() { + } + var Queue = function (name, callbacks) { + this.callbacks = assign({ + onFirstTask: noOperation, + onComplete: function () { + queueState.lastTask = null; + } + }, callbacks || {}); + this.name = name; + this.index = 0; + this.tasks = []; + this._log = false; + }; + Queue.prototype.constructor = Queue; + Queue.noop = noOperation; + Queue.prototype.enqueue = function (fn, context, args, meta) { + var len = this.tasks.push({ + fn: fn, + context: context, + args: args, + meta: meta || {} + }); + if (len === 1) { + this.callbacks.onFirstTask(this); + } + }; + Queue.prototype.flush = function () { + while (this.index < this.tasks.length) { + var task = this.tasks[this.index++]; + task.fn.apply(task.context, task.args); + } + this.index = 0; + this.tasks = []; + this.callbacks.onComplete(this); + }; + Queue.prototype.log = function () { + this._log = arguments.length ? arguments[0] : true; + }; + module.exports = Queue; +}); +/*can-queues@1.2.1#priority-queue*/ +define('can-queues@1.2.1#priority-queue', [ + 'require', + 'exports', + 'module', + './queue' +], function (require, exports, module) { + 'use strict'; + var Queue = require('./queue'); + var PriorityQueue = function () { + Queue.apply(this, arguments); + this.taskMap = new Map(); + this.taskContainersByPriority = []; + this.curPriorityIndex = Infinity; + this.curPriorityMax = 0; + this.isFlushing = false; + this.tasksRemaining = 0; + }; + PriorityQueue.prototype = Object.create(Queue.prototype); + PriorityQueue.prototype.constructor = PriorityQueue; + PriorityQueue.prototype.enqueue = function (fn, context, args, meta) { + if (!this.taskMap.has(fn)) { + this.tasksRemaining++; + var isFirst = this.taskContainersByPriority.length === 0; + var task = { + fn: fn, + context: context, + args: args, + meta: meta || {} + }; + var taskContainer = this.getTaskContainerAndUpdateRange(task); + taskContainer.tasks.push(task); + this.taskMap.set(fn, task); + if (isFirst) { + this.callbacks.onFirstTask(this); + } + } + }; + PriorityQueue.prototype.getTaskContainerAndUpdateRange = function (task) { + var priority = task.meta.priority || 0; + if (priority < this.curPriorityIndex) { + this.curPriorityIndex = priority; + } + if (priority > this.curPriorityMax) { + this.curPriorityMax = priority; + } + var tcByPriority = this.taskContainersByPriority; + var taskContainer = tcByPriority[priority]; + if (!taskContainer) { + taskContainer = tcByPriority[priority] = { + tasks: [], + index: 0 + }; + } + return taskContainer; + }; + PriorityQueue.prototype.flush = function () { + if (this.isFlushing) { + return; + } + this.isFlushing = true; + while (true) { + if (this.curPriorityIndex <= this.curPriorityMax) { + var taskContainer = this.taskContainersByPriority[this.curPriorityIndex]; + if (taskContainer && taskContainer.tasks.length > taskContainer.index) { + var task = taskContainer.tasks[taskContainer.index++]; + this.tasksRemaining--; + this.taskMap['delete'](task.fn); + task.fn.apply(task.context, task.args); + } else { + this.curPriorityIndex++; + } + } else { + this.taskMap = new Map(); + this.curPriorityIndex = Infinity; + this.curPriorityMax = 0; + this.taskContainersByPriority = []; + this.isFlushing = false; + this.callbacks.onComplete(this); + return; + } + } + }; + PriorityQueue.prototype.isEnqueued = function (fn) { + return this.taskMap.has(fn); + }; + PriorityQueue.prototype.flushQueuedTask = function (fn) { + var task = this.dequeue(fn); + if (task) { + task.fn.apply(task.context, task.args); + } + }; + PriorityQueue.prototype.dequeue = function (fn) { + var task = this.taskMap.get(fn); + if (task) { + var priority = task.meta.priority || 0; + var taskContainer = this.taskContainersByPriority[priority]; + var index = taskContainer.tasks.indexOf(task, taskContainer.index); + if (index >= 0) { + taskContainer.tasks.splice(index, 1); + this.tasksRemaining--; + this.taskMap['delete'](task.fn); + return task; + } else { + console.warn('Task', fn, 'has already run'); + } + } + }; + PriorityQueue.prototype.tasksRemainingCount = function () { + return this.tasksRemaining; + }; + module.exports = PriorityQueue; +}); +/*can-queues@1.2.1#completion-queue*/ +define('can-queues@1.2.1#completion-queue', [ + 'require', + 'exports', + 'module', + './queue' +], function (require, exports, module) { + 'use strict'; + var Queue = require('./queue'); + var CompletionQueue = function () { + Queue.apply(this, arguments); + this.flushCount = 0; + }; + CompletionQueue.prototype = Object.create(Queue.prototype); + CompletionQueue.prototype.constructor = CompletionQueue; + CompletionQueue.prototype.flush = function () { + if (this.flushCount === 0) { + this.flushCount++; + while (this.index < this.tasks.length) { + var task = this.tasks[this.index++]; + task.fn.apply(task.context, task.args); + } + this.index = 0; + this.tasks = []; + this.flushCount--; + this.callbacks.onComplete(this); + } + }; + module.exports = CompletionQueue; +}); +/*can-queues@1.2.1#can-queues*/ +define('can-queues@1.2.1#can-queues', [ + 'require', + 'exports', + 'module', + 'can-log/dev/dev', + './queue', + './priority-queue', + './queue-state', + './completion-queue', + 'can-namespace' +], function (require, exports, module) { + 'use strict'; + var canDev = require('can-log/dev/dev'); + var Queue = require('./queue'); + var PriorityQueue = require('./priority-queue'); + var queueState = require('./queue-state'); + var CompletionQueue = require('./completion-queue'); + var ns = require('can-namespace'); + var batchStartCounter = 0; + var addedTask = false; + var isFlushing = false; + var batchNum = 0; + var batchData; + var queueNames = [ + 'notify', + 'derive', + 'domUI', + 'mutate' + ]; + var NOTIFY_QUEUE, DERIVE_QUEUE, DOM_UI_QUEUE, MUTATE_QUEUE; + NOTIFY_QUEUE = new Queue('NOTIFY', { + onComplete: function () { + DERIVE_QUEUE.flush(); + }, + onFirstTask: function () { + if (!batchStartCounter) { + NOTIFY_QUEUE.flush(); + } else { + addedTask = true; + } + } + }); + DERIVE_QUEUE = new PriorityQueue('DERIVE', { + onComplete: function () { + DOM_UI_QUEUE.flush(); + }, + onFirstTask: function () { + addedTask = true; + } + }); + DOM_UI_QUEUE = new CompletionQueue('DOM_UI', { + onComplete: function () { + MUTATE_QUEUE.flush(); + }, + onFirstTask: function () { + addedTask = true; + } + }); + MUTATE_QUEUE = new Queue('MUTATE', { + onComplete: function () { + queueState.lastTask = null; + isFlushing = false; + }, + onFirstTask: function () { + addedTask = true; + } + }); + var queues = { + Queue: Queue, + PriorityQueue: PriorityQueue, + CompletionQueue: CompletionQueue, + notifyQueue: NOTIFY_QUEUE, + deriveQueue: DERIVE_QUEUE, + domUIQueue: DOM_UI_QUEUE, + mutateQueue: MUTATE_QUEUE, + batch: { + start: function () { + batchStartCounter++; + if (batchStartCounter === 1) { + batchNum++; + batchData = { number: batchNum }; + } + }, + stop: function () { + batchStartCounter--; + if (batchStartCounter === 0) { + if (addedTask) { + addedTask = false; + isFlushing = true; + NOTIFY_QUEUE.flush(); + } + } + }, + isCollecting: function () { + return batchStartCounter > 0; + }, + number: function () { + return batchNum; + }, + data: function () { + return batchData; + } + }, + runAsTask: function (fn, reasonLog) { + return fn; + }, + enqueueByQueue: function enqueueByQueue(fnByQueue, context, args, makeMeta, reasonLog) { + if (fnByQueue) { + queues.batch.start(); + queueNames.forEach(function (queueName) { + var name = queueName + 'Queue'; + var QUEUE = queues[name]; + var tasks = fnByQueue[queueName]; + if (tasks !== undefined) { + tasks.forEach(function (fn) { + var meta = makeMeta != null ? makeMeta(fn, context, args) : {}; + meta.reasonLog = reasonLog; + QUEUE.enqueue(fn, context, args, meta); + }); + } + }); + queues.batch.stop(); + } + }, + lastTask: function () { + return queueState.lastTask; + }, + stack: function (task) { + var current = task || queueState.lastTask; + var stack = []; + while (current) { + stack.unshift(current); + current = current.meta.parentTask; + } + return stack; + }, + logStack: function (task) { + var stack = this.stack(task); + stack.forEach(function (task, i) { + var meta = task.meta; + if (i === 0 && meta && meta.reasonLog) { + canDev.log.apply(canDev, meta.reasonLog); + } + var log = meta && meta.log ? meta.log : [ + task.fn.name, + task + ]; + canDev.log.apply(canDev, [task.meta.stack.name + ' ran task:'].concat(log)); + }); + }, + taskCount: function () { + return NOTIFY_QUEUE.tasks.length + DERIVE_QUEUE.tasks.length + DOM_UI_QUEUE.tasks.length + MUTATE_QUEUE.tasks.length; + }, + flush: function () { + NOTIFY_QUEUE.flush(); + }, + log: function () { + NOTIFY_QUEUE.log.apply(NOTIFY_QUEUE, arguments); + DERIVE_QUEUE.log.apply(DERIVE_QUEUE, arguments); + DOM_UI_QUEUE.log.apply(DOM_UI_QUEUE, arguments); + MUTATE_QUEUE.log.apply(MUTATE_QUEUE, arguments); + } + }; + if (ns.queues) { + throw new Error('You can\'t have two versions of can-queues, check your dependencies'); + } else { + module.exports = ns.queues = queues; + } +}); +/*can-key-tree@1.2.0#can-key-tree*/ +define('can-key-tree@1.2.0#can-key-tree', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var reflect = require('can-reflect'); + function isBuiltInPrototype(obj) { + if (obj === Object.prototype) { + return true; + } + var protoString = Object.prototype.toString.call(obj); + var isNotObjObj = protoString !== '[object Object]'; + var isObjSomething = protoString.indexOf('[object ') !== -1; + return isNotObjObj && isObjSomething; + } + function getDeepSize(root, level) { + if (level === 0) { + return reflect.size(root); + } else if (reflect.size(root) === 0) { + return 0; + } else { + var count = 0; + reflect.each(root, function (value) { + count += getDeepSize(value, level - 1); + }); + return count; + } + } + function getDeep(node, items, depth, maxDepth) { + if (!node) { + return; + } + if (maxDepth === depth) { + if (reflect.isMoreListLikeThanMapLike(node)) { + reflect.addValues(items, reflect.toArray(node)); + } else { + throw new Error('can-key-tree: Map-type leaf containers are not supported yet.'); + } + } else { + reflect.each(node, function (value) { + getDeep(value, items, depth + 1, maxDepth); + }); + } + } + function clearDeep(node, keys, maxDepth, deleteHandler) { + if (maxDepth === keys.length) { + if (reflect.isMoreListLikeThanMapLike(node)) { + var valuesToRemove = reflect.toArray(node); + if (deleteHandler) { + valuesToRemove.forEach(function (value) { + deleteHandler.apply(null, keys.concat(value)); + }); + } + reflect.removeValues(node, valuesToRemove); + } else { + throw new Error('can-key-tree: Map-type leaf containers are not supported yet.'); + } + } else { + reflect.each(node, function (value, key) { + clearDeep(value, keys.concat(key), maxDepth, deleteHandler); + reflect.deleteKeyValue(node, key); + }); + } + } + var KeyTree = function (treeStructure, callbacks) { + var FirstConstructor = treeStructure[0]; + if (reflect.isConstructorLike(FirstConstructor)) { + this.root = new FirstConstructor(); + } else { + this.root = FirstConstructor; + } + this.callbacks = callbacks || {}; + this.treeStructure = treeStructure; + this.empty = true; + }; + reflect.assign(KeyTree.prototype, { + add: function (keys) { + if (keys.length > this.treeStructure.length) { + throw new Error('can-key-tree: Can not add path deeper than tree.'); + } + var place = this.root; + var rootWasEmpty = this.empty === true; + for (var i = 0; i < keys.length - 1; i++) { + var key = keys[i]; + var childNode = reflect.getKeyValue(place, key); + if (!childNode) { + var Constructor = this.treeStructure[i + 1]; + if (isBuiltInPrototype(Constructor.prototype)) { + childNode = new Constructor(); + } else { + childNode = new Constructor(key); + } + reflect.setKeyValue(place, key, childNode); + } + place = childNode; + } + if (reflect.isMoreListLikeThanMapLike(place)) { + reflect.addValues(place, [keys[keys.length - 1]]); + } else { + throw new Error('can-key-tree: Map types are not supported yet.'); + } + if (rootWasEmpty) { + this.empty = false; + if (this.callbacks.onFirst) { + this.callbacks.onFirst.call(this); + } + } + return this; + }, + getNode: function (keys) { + var node = this.root; + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + node = reflect.getKeyValue(node, key); + if (!node) { + return; + } + } + return node; + }, + get: function (keys) { + var node = this.getNode(keys); + if (this.treeStructure.length === keys.length) { + return node; + } else { + var Type = this.treeStructure[this.treeStructure.length - 1]; + var items = new Type(); + getDeep(node, items, keys.length, this.treeStructure.length - 1); + return items; + } + }, + delete: function (keys, deleteHandler) { + var parentNode = this.root, path = [this.root], lastKey = keys[keys.length - 1]; + for (var i = 0; i < keys.length - 1; i++) { + var key = keys[i]; + var childNode = reflect.getKeyValue(parentNode, key); + if (childNode === undefined) { + return false; + } else { + path.push(childNode); + } + parentNode = childNode; + } + if (!keys.length) { + clearDeep(parentNode, [], this.treeStructure.length - 1, deleteHandler); + } else if (keys.length === this.treeStructure.length) { + if (reflect.isMoreListLikeThanMapLike(parentNode)) { + if (deleteHandler) { + deleteHandler.apply(null, keys.concat(lastKey)); + } + reflect.removeValues(parentNode, [lastKey]); + } else { + throw new Error('can-key-tree: Map types are not supported yet.'); + } + } else { + var nodeToRemove = reflect.getKeyValue(parentNode, lastKey); + if (nodeToRemove !== undefined) { + clearDeep(nodeToRemove, keys, this.treeStructure.length - 1, deleteHandler); + reflect.deleteKeyValue(parentNode, lastKey); + } else { + return false; + } + } + for (i = path.length - 2; i >= 0; i--) { + if (reflect.size(parentNode) === 0) { + parentNode = path[i]; + reflect.deleteKeyValue(parentNode, keys[i]); + } else { + break; + } + } + if (reflect.size(this.root) === 0) { + this.empty = true; + if (this.callbacks.onEmpty) { + this.callbacks.onEmpty.call(this); + } + } + return true; + }, + size: function () { + return getDeepSize(this.root, this.treeStructure.length - 1); + }, + isEmpty: function () { + return this.empty; + } + }); + module.exports = KeyTree; +}); +/*can-dom-events@1.3.3#helpers/util*/ +define('can-dom-events@1.3.3#helpers/util', [ + 'require', + 'exports', + 'module', + 'can-globals/document/document', + 'can-globals/is-browser-window/is-browser-window' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var getCurrentDocument = require('can-globals/document/document'); + var isBrowserWindow = require('can-globals/is-browser-window/is-browser-window'); + function getTargetDocument(target) { + return target.ownerDocument || getCurrentDocument(); + } + function createEvent(target, eventData, bubbles, cancelable) { + var doc = getTargetDocument(target); + var event = doc.createEvent('HTMLEvents'); + var eventType; + if (typeof eventData === 'string') { + eventType = eventData; + } else { + eventType = eventData.type; + for (var prop in eventData) { + if (event[prop] === undefined) { + event[prop] = eventData[prop]; + } + } + } + if (bubbles === undefined) { + bubbles = true; + } + event.initEvent(eventType, bubbles, cancelable); + return event; + } + function isDomEventTarget(obj) { + if (!(obj && obj.nodeName)) { + return obj === window; + } + var nodeType = obj.nodeType; + return nodeType === 1 || nodeType === 9 || nodeType === 11; + } + function addDomContext(context, args) { + if (isDomEventTarget(context)) { + args = Array.prototype.slice.call(args, 0); + args.unshift(context); + } + return args; + } + function removeDomContext(context, args) { + if (!isDomEventTarget(context)) { + args = Array.prototype.slice.call(args, 0); + context = args.shift(); + } + return { + context: context, + args: args + }; + } + var fixSyntheticEventsOnDisabled = false; + (function () { + if (!isBrowserWindow()) { + return; + } + var testEventName = 'fix_synthetic_events_on_disabled_test'; + var input = document.createElement('input'); + input.disabled = true; + var timer = setTimeout(function () { + fixSyntheticEventsOnDisabled = true; + }, 50); + var onTest = function onTest() { + clearTimeout(timer); + input.removeEventListener(testEventName, onTest); + }; + input.addEventListener(testEventName, onTest); + try { + var event = document.create('HTMLEvents'); + event.initEvent(testEventName, false); + input.dispatchEvent(event); + } catch (e) { + onTest(); + fixSyntheticEventsOnDisabled = true; + } + }()); + function isDispatchingOnDisabled(element, event) { + var eventType = event.type; + var isInsertedOrRemoved = eventType === 'inserted' || eventType === 'removed'; + var isDisabled = !!element.disabled; + return isInsertedOrRemoved && isDisabled; + } + function forceEnabledForDispatch(element, event) { + return fixSyntheticEventsOnDisabled && isDispatchingOnDisabled(element, event); + } + module.exports = { + createEvent: createEvent, + addDomContext: addDomContext, + removeDomContext: removeDomContext, + isDomEventTarget: isDomEventTarget, + getTargetDocument: getTargetDocument, + forceEnabledForDispatch: forceEnabledForDispatch + }; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-dom-events@1.3.3#helpers/make-event-registry*/ +define('can-dom-events@1.3.3#helpers/make-event-registry', function (require, exports, module) { + 'use strict'; + function EventRegistry() { + this._registry = {}; + } + module.exports = function makeEventRegistry() { + return new EventRegistry(); + }; + EventRegistry.prototype.has = function (eventType) { + return !!this._registry[eventType]; + }; + EventRegistry.prototype.get = function (eventType) { + return this._registry[eventType]; + }; + EventRegistry.prototype.add = function (event, eventType) { + if (!event) { + throw new Error('An EventDefinition must be provided'); + } + if (typeof event.addEventListener !== 'function') { + throw new TypeError('EventDefinition addEventListener must be a function'); + } + if (typeof event.removeEventListener !== 'function') { + throw new TypeError('EventDefinition removeEventListener must be a function'); + } + eventType = eventType || event.defaultEventType; + if (typeof eventType !== 'string') { + throw new TypeError('Event type must be a string, not ' + eventType); + } + if (this.has(eventType)) { + throw new Error('Event "' + eventType + '" is already registered'); + } + this._registry[eventType] = event; + var self = this; + return function remove() { + self._registry[eventType] = undefined; + }; + }; +}); +/*can-dom-events@1.3.3#helpers/-make-delegate-event-tree*/ +define('can-dom-events@1.3.3#helpers/-make-delegate-event-tree', [ + 'require', + 'exports', + 'module', + 'can-key-tree', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var KeyTree = require('can-key-tree'); + var canReflect = require('can-reflect'); + var useCapture = function (eventType) { + return eventType === 'focus' || eventType === 'blur'; + }; + function makeDelegator(domEvents) { + var Delegator = function Delegator(parentKey) { + this.element = parentKey; + this.events = {}; + this.delegated = {}; + }; + canReflect.assignSymbols(Delegator.prototype, { + 'can.setKeyValue': function (eventType, handlersBySelector) { + var handler = this.delegated[eventType] = function (ev) { + canReflect.each(handlersBySelector, function (handlers, selector) { + var cur = ev.target; + do { + var el = cur === document ? document.documentElement : cur; + var matches = el.matches || el.msMatchesSelector; + if (matches && matches.call(el, selector)) { + handlers.forEach(function (handler) { + handler.call(el, ev); + }); + } + cur = cur.parentNode; + } while (cur && cur !== ev.currentTarget); + }); + }; + this.events[eventType] = handlersBySelector; + domEvents.addEventListener(this.element, eventType, handler, useCapture(eventType)); + }, + 'can.getKeyValue': function (eventType) { + return this.events[eventType]; + }, + 'can.deleteKeyValue': function (eventType) { + domEvents.removeEventListener(this.element, eventType, this.delegated[eventType], useCapture(eventType)); + delete this.delegated[eventType]; + delete this.events[eventType]; + }, + 'can.getOwnEnumerableKeys': function () { + return Object.keys(this.events); + } + }); + return Delegator; + } + module.exports = function makeDelegateEventTree(domEvents) { + var Delegator = makeDelegator(domEvents); + return new KeyTree([ + Map, + Delegator, + Object, + Array + ]); + }; +}); +/*can-dom-events@1.3.3#can-dom-events*/ +define('can-dom-events@1.3.3#can-dom-events', [ + 'require', + 'exports', + 'module', + 'can-namespace', + './helpers/util', + './helpers/make-event-registry', + './helpers/-make-delegate-event-tree' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + var util = require('./helpers/util'); + var makeEventRegistry = require('./helpers/make-event-registry'); + var makeDelegateEventTree = require('./helpers/-make-delegate-event-tree'); + var domEvents = { + _eventRegistry: makeEventRegistry(), + addEvent: function (event, eventType) { + return this._eventRegistry.add(event, eventType); + }, + addEventListener: function (target, eventType) { + var hasCustomEvent = domEvents._eventRegistry.has(eventType); + if (hasCustomEvent) { + var event = domEvents._eventRegistry.get(eventType); + return event.addEventListener.apply(domEvents, arguments); + } + var eventArgs = Array.prototype.slice.call(arguments, 1); + return target.addEventListener.apply(target, eventArgs); + }, + removeEventListener: function (target, eventType) { + var hasCustomEvent = domEvents._eventRegistry.has(eventType); + if (hasCustomEvent) { + var event = domEvents._eventRegistry.get(eventType); + return event.removeEventListener.apply(domEvents, arguments); + } + var eventArgs = Array.prototype.slice.call(arguments, 1); + return target.removeEventListener.apply(target, eventArgs); + }, + addDelegateListener: function (root, eventType, selector, handler) { + domEvents._eventTree.add([ + root, + eventType, + selector, + handler + ]); + }, + removeDelegateListener: function (target, eventType, selector, handler) { + domEvents._eventTree.delete([ + target, + eventType, + selector, + handler + ]); + }, + dispatch: function (target, eventData, bubbles, cancelable) { + var event = util.createEvent(target, eventData, bubbles, cancelable); + var enableForDispatch = util.forceEnabledForDispatch(target, event); + if (enableForDispatch) { + target.disabled = false; + } + var ret = target.dispatchEvent(event); + if (enableForDispatch) { + target.disabled = true; + } + return ret; + } + }; + domEvents._eventTree = makeDelegateEventTree(domEvents); + module.exports = namespace.domEvents = domEvents; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-event-queue@1.1.3#dependency-record/merge*/ +define('can-event-queue@1.1.3#dependency-record/merge', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var mergeValueDependencies = function mergeValueDependencies(obj, source) { + var sourceValueDeps = source.valueDependencies; + if (sourceValueDeps) { + var destValueDeps = obj.valueDependencies; + if (!destValueDeps) { + destValueDeps = new Set(); + obj.valueDependencies = destValueDeps; + } + canReflect.eachIndex(sourceValueDeps, function (dep) { + destValueDeps.add(dep); + }); + } + }; + var mergeKeyDependencies = function mergeKeyDependencies(obj, source) { + var sourcekeyDeps = source.keyDependencies; + if (sourcekeyDeps) { + var destKeyDeps = obj.keyDependencies; + if (!destKeyDeps) { + destKeyDeps = new Map(); + obj.keyDependencies = destKeyDeps; + } + canReflect.eachKey(sourcekeyDeps, function (keys, obj) { + var entry = destKeyDeps.get(obj); + if (!entry) { + entry = new Set(); + destKeyDeps.set(obj, entry); + } + canReflect.eachIndex(keys, function (key) { + entry.add(key); + }); + }); + } + }; + module.exports = function mergeDependencyRecords(object, source) { + mergeKeyDependencies(object, source); + mergeValueDependencies(object, source); + return object; + }; +}); +/*can-event-queue@1.1.3#map/map*/ +define('can-event-queue@1.1.3#map/map', [ + 'require', + 'exports', + 'module', + 'can-log/dev/dev', + 'can-queues', + 'can-reflect', + 'can-symbol', + 'can-key-tree', + 'can-dom-events', + 'can-dom-events/helpers/util', + '../dependency-record/merge' +], function (require, exports, module) { + 'use strict'; + var canDev = require('can-log/dev/dev'); + var queues = require('can-queues'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var KeyTree = require('can-key-tree'); + var domEvents = require('can-dom-events'); + var isDomEventTarget = require('can-dom-events/helpers/util').isDomEventTarget; + var mergeDependencyRecords = require('../dependency-record/merge'); + var metaSymbol = canSymbol.for('can.meta'), dispatchBoundChangeSymbol = canSymbol.for('can.dispatchInstanceBoundChange'), dispatchInstanceOnPatchesSymbol = canSymbol.for('can.dispatchInstanceOnPatches'), onKeyValueSymbol = canSymbol.for('can.onKeyValue'), offKeyValueSymbol = canSymbol.for('can.offKeyValue'), onEventSymbol = canSymbol.for('can.onEvent'), offEventSymbol = canSymbol.for('can.offEvent'), onValueSymbol = canSymbol.for('can.onValue'), offValueSymbol = canSymbol.for('can.offValue'); + var legacyMapBindings; + function addHandlers(obj, meta) { + if (!meta.handlers) { + meta.handlers = new KeyTree([ + Object, + Object, + Object, + Array + ], { + onFirst: function () { + if (obj._eventSetup !== undefined) { + obj._eventSetup(); + } + var constructor = obj.constructor; + if (constructor[dispatchBoundChangeSymbol] !== undefined && obj instanceof constructor) { + constructor[dispatchBoundChangeSymbol](obj, true); + } + }, + onEmpty: function () { + if (obj._eventTeardown !== undefined) { + obj._eventTeardown(); + } + var constructor = obj.constructor; + if (constructor[dispatchBoundChangeSymbol] !== undefined && obj instanceof constructor) { + constructor[dispatchBoundChangeSymbol](obj, false); + } + } + }); + } + if (!meta.listenHandlers) { + meta.listenHandlers = new KeyTree([ + Map, + Map, + Object, + Array + ]); + } + } + var ensureMeta = function ensureMeta(obj) { + var meta = obj[metaSymbol]; + if (!meta) { + meta = {}; + canReflect.setKeyValue(obj, metaSymbol, meta); + } + addHandlers(obj, meta); + return meta; + }; + function stopListeningArgumentsToKeys(bindTarget, event, handler, queueName) { + if (arguments.length && canReflect.isPrimitive(bindTarget)) { + queueName = handler; + handler = event; + event = bindTarget; + bindTarget = this.context; + } + if (typeof event === 'function') { + queueName = handler; + handler = event; + event = undefined; + } + if (typeof handler === 'string') { + queueName = handler; + handler = undefined; + } + var keys = []; + if (bindTarget) { + keys.push(bindTarget); + if (event || handler || queueName) { + keys.push(event); + if (queueName || handler) { + keys.push(queueName || this.defaultQueue); + if (handler) { + keys.push(handler); + } + } + } + } + return keys; + } + var props = { + dispatch: function (event, args) { + if (!this.__inSetup) { + if (typeof event === 'string') { + event = { type: event }; + } + var meta = ensureMeta(this); + var handlers = meta.handlers; + var handlersByType = event.type !== undefined && handlers.getNode([event.type]); + var dispatchConstructorPatches = event.patches && this.constructor[dispatchInstanceOnPatchesSymbol]; + var patchesNode = event.patches !== undefined && handlers.getNode([ + 'can.patches', + 'onKeyValue' + ]); + var keysNode = event.keyChanged !== undefined && handlers.getNode([ + 'can.keys', + 'onKeyValue' + ]); + var batch = dispatchConstructorPatches || handlersByType || patchesNode || keysNode; + if (batch) { + queues.batch.start(); + } + if (handlersByType) { + if (handlersByType.onKeyValue) { + queues.enqueueByQueue(handlersByType.onKeyValue, this, args, event.makeMeta, event.reasonLog); + } + if (handlersByType.event) { + event.batchNum = queues.batch.number(); + var eventAndArgs = [event].concat(args); + queues.enqueueByQueue(handlersByType.event, this, eventAndArgs, event.makeMeta, event.reasonLog); + } + } + if (keysNode) { + queues.enqueueByQueue(keysNode, this, [event.keyChanged], event.makeMeta, event.reasonLog); + } + if (patchesNode) { + queues.enqueueByQueue(patchesNode, this, [event.patches], event.makeMeta, event.reasonLog); + } + if (dispatchConstructorPatches) { + this.constructor[dispatchInstanceOnPatchesSymbol](this, event.patches); + } + if (batch) { + queues.batch.stop(); + } + } + return event; + }, + addEventListener: function (key, handler, queueName) { + ensureMeta(this).handlers.add([ + key, + 'event', + queueName || 'mutate', + handler + ]); + return this; + }, + removeEventListener: function (key, handler, queueName) { + if (key === undefined) { + var handlers = ensureMeta(this).handlers; + var keyHandlers = handlers.getNode([]); + Object.keys(keyHandlers).forEach(function (key) { + handlers.delete([ + key, + 'event' + ]); + }); + } else if (!handler && !queueName) { + ensureMeta(this).handlers.delete([ + key, + 'event' + ]); + } else if (!handler) { + ensureMeta(this).handlers.delete([ + key, + 'event', + queueName || 'mutate' + ]); + } else { + ensureMeta(this).handlers.delete([ + key, + 'event', + queueName || 'mutate', + handler + ]); + } + return this; + }, + one: function (event, handler) { + var one = function () { + legacyMapBindings.off.call(this, event, one); + return handler.apply(this, arguments); + }; + legacyMapBindings.on.call(this, event, one); + return this; + }, + listenTo: function (bindTarget, event, handler, queueName) { + if (canReflect.isPrimitive(bindTarget)) { + queueName = handler; + handler = event; + event = bindTarget; + bindTarget = this; + } + if (typeof event === 'function') { + queueName = handler; + handler = event; + event = undefined; + } + ensureMeta(this).listenHandlers.add([ + bindTarget, + event, + queueName || 'mutate', + handler + ]); + legacyMapBindings.on.call(bindTarget, event, handler, queueName || 'mutate'); + return this; + }, + stopListening: function () { + var keys = stopListeningArgumentsToKeys.apply({ + context: this, + defaultQueue: 'mutate' + }, arguments); + var listenHandlers = ensureMeta(this).listenHandlers; + function deleteHandler(bindTarget, event, queue, handler) { + legacyMapBindings.off.call(bindTarget, event, handler, queue); + } + listenHandlers.delete(keys, deleteHandler); + return this; + }, + on: function (eventName, handler, queue) { + var listenWithDOM = isDomEventTarget(this); + if (listenWithDOM) { + if (typeof handler === 'string') { + domEvents.addDelegateListener(this, eventName, handler, queue); + } else { + domEvents.addEventListener(this, eventName, handler, queue); + } + } else { + if ('addEventListener' in this) { + this.addEventListener(eventName, handler, queue); + } else if (this[onKeyValueSymbol]) { + canReflect.onKeyValue(this, eventName, handler, queue); + } else if (this[onEventSymbol]) { + this[onEventSymbol](eventName, handler, queue); + } else { + if (!eventName && this[onValueSymbol]) { + canReflect.onValue(this, handler, queue); + } else { + throw new Error('can-event-queue: Unable to bind ' + eventName); + } + } + } + return this; + }, + off: function (eventName, handler, queue) { + var listenWithDOM = isDomEventTarget(this); + if (listenWithDOM) { + if (typeof handler === 'string') { + domEvents.removeDelegateListener(this, eventName, handler, queue); + } else { + domEvents.removeEventListener(this, eventName, handler, queue); + } + } else { + if ('removeEventListener' in this) { + this.removeEventListener(eventName, handler, queue); + } else if (this[offKeyValueSymbol]) { + canReflect.offKeyValue(this, eventName, handler, queue); + } else if (this[offEventSymbol]) { + this[offEventSymbol](eventName, handler, queue); + } else { + if (!eventName && this[offValueSymbol]) { + canReflect.offValue(this, handler, queue); + } else { + throw new Error('can-event-queue: Unable to unbind ' + eventName); + } + } + } + return this; + } + }; + var symbols = { + 'can.onKeyValue': function (key, handler, queueName) { + ensureMeta(this).handlers.add([ + key, + 'onKeyValue', + queueName || 'mutate', + handler + ]); + }, + 'can.offKeyValue': function (key, handler, queueName) { + ensureMeta(this).handlers.delete([ + key, + 'onKeyValue', + queueName || 'mutate', + handler + ]); + }, + 'can.isBound': function () { + return !ensureMeta(this).handlers.isEmpty(); + }, + 'can.getWhatIChange': function getWhatIChange(key) { + }, + 'can.onPatches': function (handler, queue) { + var handlers = ensureMeta(this).handlers; + handlers.add([ + 'can.patches', + 'onKeyValue', + queue || 'notify', + handler + ]); + }, + 'can.offPatches': function (handler, queue) { + var handlers = ensureMeta(this).handlers; + handlers.delete([ + 'can.patches', + 'onKeyValue', + queue || 'notify', + handler + ]); + } + }; + function defineNonEnumerable(obj, prop, value) { + Object.defineProperty(obj, prop, { + enumerable: false, + value: value + }); + } + legacyMapBindings = function (obj) { + canReflect.assignMap(obj, props); + return canReflect.assignSymbols(obj, symbols); + }; + defineNonEnumerable(legacyMapBindings, 'addHandlers', addHandlers); + defineNonEnumerable(legacyMapBindings, 'stopListeningArgumentsToKeys', stopListeningArgumentsToKeys); + props.bind = props.addEventListener; + props.unbind = props.removeEventListener; + canReflect.assignMap(legacyMapBindings, props); + canReflect.assignSymbols(legacyMapBindings, symbols); + defineNonEnumerable(legacyMapBindings, 'start', function () { + console.warn('use can-queues.batch.start()'); + queues.batch.start(); + }); + defineNonEnumerable(legacyMapBindings, 'stop', function () { + console.warn('use can-queues.batch.stop()'); + queues.batch.stop(); + }); + defineNonEnumerable(legacyMapBindings, 'flush', function () { + console.warn('use can-queues.flush()'); + queues.flush(); + }); + defineNonEnumerable(legacyMapBindings, 'afterPreviousEvents', function (handler) { + console.warn('don\'t use afterPreviousEvents'); + queues.mutateQueue.enqueue(function afterPreviousEvents() { + queues.mutateQueue.enqueue(handler); + }); + queues.flush(); + }); + defineNonEnumerable(legacyMapBindings, 'after', function (handler) { + console.warn('don\'t use after'); + queues.mutateQueue.enqueue(handler); + queues.flush(); + }); + module.exports = legacyMapBindings; +}); +/*can-observation-recorder@1.2.0#can-observation-recorder*/ +define('can-observation-recorder@1.2.0#can-observation-recorder', [ + 'require', + 'exports', + 'module', + 'can-namespace', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + var canSymbol = require('can-symbol'); + var stack = []; + var addParentSymbol = canSymbol.for('can.addParent'); + var ObservationRecorder = { + stack: stack, + start: function () { + var deps = { + keyDependencies: new Map(), + valueDependencies: new Set(), + childDependencies: new Set(), + traps: null, + ignore: 0 + }; + stack.push(deps); + return deps; + }, + stop: function () { + return stack.pop(); + }, + add: function (obj, event) { + var top = stack[stack.length - 1]; + if (top && top.ignore === 0) { + if (top.traps) { + top.traps.push([ + obj, + event + ]); + } else { + if (event === undefined) { + top.valueDependencies.add(obj); + } else { + var eventSet = top.keyDependencies.get(obj); + if (!eventSet) { + eventSet = new Set(); + top.keyDependencies.set(obj, eventSet); + } + eventSet.add(event); + } + } + } + }, + addMany: function (observes) { + var top = stack[stack.length - 1]; + if (top) { + if (top.traps) { + top.traps.push.apply(top.traps, observes); + } else { + for (var i = 0, len = observes.length; i < len; i++) { + this.add(observes[i][0], observes[i][1]); + } + } + } + }, + created: function (obs) { + var top = stack[stack.length - 1]; + if (top) { + top.childDependencies.add(obs); + if (obs[addParentSymbol]) { + obs[addParentSymbol](top); + } + } + }, + ignore: function (fn) { + return function () { + if (stack.length) { + var top = stack[stack.length - 1]; + top.ignore++; + var res = fn.apply(this, arguments); + top.ignore--; + return res; + } else { + return fn.apply(this, arguments); + } + }; + }, + isRecording: function () { + var len = stack.length; + var last = len && stack[len - 1]; + return last && last.ignore === 0 && last; + }, + makeDependenciesRecord: function () { + return { + traps: null, + keyDependencies: new Map(), + valueDependencies: new Set(), + ignore: 0 + }; + }, + makeDependenciesRecorder: function () { + return ObservationRecorder.makeDependenciesRecord(); + }, + trap: function () { + if (stack.length) { + var top = stack[stack.length - 1]; + var oldTraps = top.traps; + var traps = top.traps = []; + return function () { + top.traps = oldTraps; + return traps; + }; + } else { + return function () { + return []; + }; + } + }, + trapsCount: function () { + if (stack.length) { + var top = stack[stack.length - 1]; + return top.traps.length; + } else { + return 0; + } + } + }; + if (namespace.ObservationRecorder) { + throw new Error('You can\'t have two versions of can-observation-recorder, check your dependencies'); + } else { + module.exports = namespace.ObservationRecorder = ObservationRecorder; + } +}); +/*can-simple-map@4.3.0#can-simple-map*/ +define('can-simple-map@4.3.0#can-simple-map', [ + 'require', + 'exports', + 'module', + 'can-construct', + 'can-event-queue/map/map', + 'can-queues', + 'can-observation-recorder', + 'can-reflect', + 'can-log/dev/dev', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var Construct = require('can-construct'); + var eventQueue = require('can-event-queue/map/map'); + var queues = require('can-queues'); + var ObservationRecorder = require('can-observation-recorder'); + var canReflect = require('can-reflect'); + var dev = require('can-log/dev/dev'); + var canSymbol = require('can-symbol'); + var ensureMeta = function ensureMeta(obj) { + var metaSymbol = canSymbol.for('can.meta'); + var meta = obj[metaSymbol]; + if (!meta) { + meta = {}; + canReflect.setKeyValue(obj, metaSymbol, meta); + } + return meta; + }; + var SimpleMap = Construct.extend('SimpleMap', { + setup: function (initialData) { + this._data = {}; + if (initialData && typeof initialData === 'object') { + this.attr(initialData); + } + }, + attr: function (prop, value) { + var self = this; + if (arguments.length === 0) { + ObservationRecorder.add(this, 'can.keys'); + var data = {}; + canReflect.eachKey(this._data, function (value, prop) { + ObservationRecorder.add(this, prop); + data[prop] = value; + }, this); + return data; + } else if (arguments.length > 1) { + var had = this._data.hasOwnProperty(prop); + var old = this._data[prop]; + this._data[prop] = value; + if (old !== value) { + var dispatched = { + keyChanged: !had ? prop : undefined, + type: prop + }; + this.dispatch(dispatched, [ + value, + old + ]); + } + } else if (typeof prop === 'object') { + queues.batch.start(); + canReflect.eachKey(prop, function (value, key) { + self.attr(key, value); + }); + queues.batch.stop(); + } else { + if (prop !== 'constructor') { + ObservationRecorder.add(this, prop); + return this._data[prop]; + } + return this.constructor; + } + }, + serialize: function () { + return canReflect.serialize(this, Map); + }, + get: function () { + return this.attr.apply(this, arguments); + }, + set: function () { + return this.attr.apply(this, arguments); + }, + log: function (key) { + } + }); + eventQueue(SimpleMap.prototype); + var simpleMapProto = { + 'can.isMapLike': true, + 'can.isListLike': false, + 'can.isValueLike': false, + 'can.getKeyValue': SimpleMap.prototype.get, + 'can.setKeyValue': SimpleMap.prototype.set, + 'can.deleteKeyValue': function (prop) { + var dispatched; + if (this._data.hasOwnProperty(prop)) { + var old = this._data[prop]; + delete this._data[prop]; + dispatched = { + keyChanged: prop, + type: prop + }; + this.dispatch(dispatched, [ + undefined, + old + ]); + } + }, + 'can.getOwnEnumerableKeys': function () { + ObservationRecorder.add(this, 'can.keys'); + return Object.keys(this._data); + }, + 'can.assignDeep': function (source) { + queues.batch.start(); + canReflect.assignMap(this, source); + queues.batch.stop(); + }, + 'can.updateDeep': function (source) { + queues.batch.start(); + canReflect.updateMap(this, source); + queues.batch.stop(); + }, + 'can.keyHasDependencies': function (key) { + return false; + }, + 'can.getKeyDependencies': function (key) { + return undefined; + }, + 'can.hasOwnKey': function (key) { + return this._data.hasOwnProperty(key); + } + }; + canReflect.assignSymbols(SimpleMap.prototype, simpleMapProto); + module.exports = SimpleMap; +}); +/*can-view-nodelist@4.3.2#can-view-nodelist*/ +define('can-view-nodelist@4.3.2#can-view-nodelist', [ + 'require', + 'exports', + 'module', + 'can-namespace', + 'can-dom-mutate/node' +], function (require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + var domMutate = require('can-dom-mutate/node'); + var nodeMap = new Map(), splice = [].splice, push = [].push, itemsInChildListTree = function (list) { + var count = 0; + for (var i = 0, len = list.length; i < len; i++) { + var item = list[i]; + if (item.nodeType) { + count++; + } else { + count += itemsInChildListTree(item); + } + } + return count; + }, replacementMap = function (replacements) { + var map = new Map(); + for (var i = 0, len = replacements.length; i < len; i++) { + var node = nodeLists.first(replacements[i]); + map.set(node, replacements[i]); + } + return map; + }, addUnfoundAsDeepChildren = function (list, rMap) { + rMap.forEach(function (replacement) { + list.newDeepChildren.push(replacement); + }); + }; + var nodeLists = { + update: function (nodeList, newNodes, oldNodes) { + if (!oldNodes) { + oldNodes = nodeLists.unregisterChildren(nodeList); + } + var arr = []; + for (var i = 0, ref = arr.length = newNodes.length; i < ref; i++) { + arr[i] = newNodes[i]; + } + newNodes = arr; + var oldListLength = nodeList.length; + splice.apply(nodeList, [ + 0, + oldListLength + ].concat(newNodes)); + if (nodeList.replacements) { + nodeLists.nestReplacements(nodeList); + nodeList.deepChildren = nodeList.newDeepChildren; + nodeList.newDeepChildren = []; + } else { + nodeLists.nestList(nodeList); + } + return oldNodes; + }, + nestReplacements: function (list) { + var index = 0, rMap = replacementMap(list.replacements), rCount = list.replacements.length; + while (index < list.length && rCount) { + var node = list[index], replacement = rMap.get(node); + if (replacement) { + rMap['delete'](node); + list.splice(index, itemsInChildListTree(replacement), replacement); + rCount--; + } + index++; + } + if (rCount) { + addUnfoundAsDeepChildren(list, rMap); + } + list.replacements = []; + }, + nestList: function (list) { + var index = 0; + while (index < list.length) { + var node = list[index], childNodeList = nodeMap.get(node); + if (childNodeList) { + if (childNodeList !== list) { + list.splice(index, itemsInChildListTree(childNodeList), childNodeList); + } + } else { + nodeMap.set(node, list); + } + index++; + } + }, + last: function (nodeList) { + var last = nodeList[nodeList.length - 1]; + if (last.nodeType) { + return last; + } else { + return nodeLists.last(last); + } + }, + first: function (nodeList) { + var first = nodeList[0]; + if (first.nodeType) { + return first; + } else { + return nodeLists.first(first); + } + }, + flatten: function (nodeList) { + var items = []; + for (var i = 0; i < nodeList.length; i++) { + var item = nodeList[i]; + if (item.nodeType) { + items.push(item); + } else { + items.push.apply(items, nodeLists.flatten(item)); + } + } + return items; + }, + register: function (nodeList, unregistered, parent, directlyNested) { + nodeList.unregistered = unregistered; + nodeList.parentList = parent; + nodeList.nesting = parent && typeof parent.nesting !== 'undefined' ? parent.nesting + 1 : 0; + if (parent) { + nodeList.deepChildren = []; + nodeList.newDeepChildren = []; + nodeList.replacements = []; + if (parent !== true) { + if (directlyNested) { + parent.replacements.push(nodeList); + } else { + parent.newDeepChildren.push(nodeList); + } + } + } else { + nodeLists.nestList(nodeList); + } + return nodeList; + }, + unregisterChildren: function (nodeList) { + var nodes = []; + for (var n = 0; n < nodeList.length; n++) { + var node = nodeList[n]; + if (node.nodeType) { + if (!nodeList.replacements) { + nodeMap['delete'](node); + } + nodes.push(node); + } else { + push.apply(nodes, nodeLists.unregister(node, true)); + } + } + var deepChildren = nodeList.deepChildren; + if (deepChildren) { + for (var l = 0; l < deepChildren.length; l++) { + nodeLists.unregister(deepChildren[l], true); + } + } + return nodes; + }, + unregister: function (nodeList, isChild) { + var nodes = nodeLists.unregisterChildren(nodeList, true); + nodeList.isUnregistered = true; + if (nodeList.unregistered) { + var unregisteredCallback = nodeList.unregistered; + nodeList.replacements = nodeList.unregistered = null; + if (!isChild) { + var deepChildren = nodeList.parentList && nodeList.parentList.deepChildren; + if (deepChildren) { + var index = deepChildren.indexOf(nodeList); + if (index !== -1) { + deepChildren.splice(index, 1); + } + } + } + unregisteredCallback(); + } + return nodes; + }, + after: function (oldElements, newFrag) { + var last = oldElements[oldElements.length - 1]; + if (last.nextSibling) { + domMutate.insertBefore.call(last.parentNode, newFrag, last.nextSibling); + } else { + domMutate.appendChild.call(last.parentNode, newFrag); + } + }, + replace: function (oldElements, newFrag) { + var selectedValue, parentNode = oldElements[0].parentNode; + if (parentNode.nodeName.toUpperCase() === 'SELECT' && parentNode.selectedIndex >= 0) { + selectedValue = parentNode.value; + } + if (oldElements.length === 1) { + domMutate.replaceChild.call(parentNode, newFrag, oldElements[0]); + } else { + nodeLists.after(oldElements, newFrag); + nodeLists.remove(oldElements); + } + if (selectedValue !== undefined) { + parentNode.value = selectedValue; + } + }, + remove: function (elementsToBeRemoved) { + var parent = elementsToBeRemoved[0] && elementsToBeRemoved[0].parentNode; + for (var i = 0; i < elementsToBeRemoved.length; i++) { + domMutate.removeChild.call(parent, elementsToBeRemoved[i]); + } + }, + nodeMap: nodeMap + }; + module.exports = namespace.nodeLists = nodeLists; +}); +/*can-child-nodes@1.2.0#can-child-nodes*/ +define('can-child-nodes@1.2.0#can-child-nodes', [ + 'require', + 'exports', + 'module', + 'can-namespace' +], function (require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + function childNodes(node) { + var childNodes = node.childNodes; + if ('length' in childNodes) { + return childNodes; + } else { + var cur = node.firstChild; + var nodes = []; + while (cur) { + nodes.push(cur); + cur = cur.nextSibling; + } + return nodes; + } + } + module.exports = namespace.childNodes = childNodes; +}); +/*can-fragment@1.3.0#can-fragment*/ +define('can-fragment@1.3.0#can-fragment', [ + 'require', + 'exports', + 'module', + 'can-globals/document/document', + 'can-namespace', + 'can-reflect', + 'can-child-nodes', + 'can-symbol' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var getDocument = require('can-globals/document/document'); + var namespace = require('can-namespace'); + var canReflect = require('can-reflect'); + var childNodes = require('can-child-nodes'); + var canSymbol = require('can-symbol'); + var fragmentRE = /^\s*<(\w+)[^>]*>/, toString = {}.toString, toDOMSymbol = canSymbol.for('can.toDOM'); + function makeFragment(html, name, doc) { + if (name === undefined) { + name = fragmentRE.test(html) && RegExp.$1; + } + if (html && toString.call(html.replace) === '[object Function]') { + html = html.replace(/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, '<$1>'); + } + var container = doc.createElement('div'), temp = doc.createElement('div'); + if (name === 'tbody' || name === 'tfoot' || name === 'thead' || name === 'colgroup') { + temp.innerHTML = '' + html + '
    '; + container = temp.firstChild.nodeType === 3 ? temp.lastChild : temp.firstChild; + } else if (name === 'col') { + temp.innerHTML = '' + html + '
    '; + container = temp.firstChild.nodeType === 3 ? temp.lastChild : temp.firstChild.firstChild; + } else if (name === 'tr') { + temp.innerHTML = '' + html + '
    '; + container = temp.firstChild.nodeType === 3 ? temp.lastChild : temp.firstChild.firstChild; + } else if (name === 'td' || name === 'th') { + temp.innerHTML = '' + html + '
    '; + container = temp.firstChild.nodeType === 3 ? temp.lastChild : temp.firstChild.firstChild.firstChild; + } else if (name === 'option') { + temp.innerHTML = ''; + container = temp.firstChild.nodeType === 3 ? temp.lastChild : temp.firstChild; + } else { + container.innerHTML = '' + html; + } + return [].slice.call(childNodes(container)); + } + function fragment(html, doc) { + if (html && html.nodeType === 11) { + return html; + } + if (!doc) { + doc = getDocument(); + } else if (doc.length) { + doc = doc[0]; + } + var parts = makeFragment(html, undefined, doc), frag = (doc || document).createDocumentFragment(); + for (var i = 0, length = parts.length; i < length; i++) { + frag.appendChild(parts[i]); + } + return frag; + } + var makeFrag = function (item, doc) { + var document = doc || getDocument(); + var frag; + if (!item || typeof item === 'string') { + frag = fragment(item == null ? '' : '' + item, document); + } else if (typeof item[toDOMSymbol] === 'function') { + return makeFrag(item[toDOMSymbol]()); + } else if (item.nodeType === 11) { + return item; + } else if (typeof item.nodeType === 'number') { + frag = document.createDocumentFragment(); + frag.appendChild(item); + return frag; + } else if (canReflect.isListLike(item)) { + frag = document.createDocumentFragment(); + canReflect.eachIndex(item, function (item) { + frag.appendChild(makeFrag(item)); + }); + } else { + frag = fragment('' + item, document); + } + if (!childNodes(frag).length) { + frag.appendChild(document.createTextNode('')); + } + return frag; + }; + module.exports = namespace.fragment = namespace.frag = makeFrag; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-view-callbacks@4.3.2#can-view-callbacks*/ +define('can-view-callbacks@4.3.2#can-view-callbacks', [ + 'require', + 'exports', + 'module', + 'can-observation-recorder', + 'can-log/dev/dev', + 'can-globals/global/global', + 'can-dom-mutate/node', + 'can-namespace', + 'can-view-nodelist', + 'can-fragment', + 'can-globals', + 'can-symbol', + 'can-reflect' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var ObservationRecorder = require('can-observation-recorder'); + var dev = require('can-log/dev/dev'); + var getGlobal = require('can-globals/global/global'); + var domMutate = require('can-dom-mutate/node'); + var namespace = require('can-namespace'); + var nodeLists = require('can-view-nodelist'); + var makeFrag = require('can-fragment'); + var globals = require('can-globals'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + var callbackMapSymbol = canSymbol.for('can.callbackMap'); + var tags = {}; + var automountEnabled = function () { + var document = globals.getKeyValue('document'); + if (document == null || document.documentElement == null) { + return false; + } + return document.documentElement.getAttribute('data-can-automount') !== 'false'; + }; + var renderedElements = new WeakMap(); + var mountElement = function (node) { + var tagName = node.tagName && node.tagName.toLowerCase(); + var tagHandler = tags[tagName]; + if (tagHandler) { + callbacks.tagHandler(node, tagName, {}); + } + }; + var renderNodeAndChildren = function (node) { + var children; + mountElement(node); + if (node.getElementsByTagName) { + children = node.getElementsByTagName('*'); + for (var k = 0, child; (child = children[k]) !== undefined; k++) { + renderNodeAndChildren(child); + } + } + }; + var mutationObserverEnabled = false; + var globalMutationObserver; + var enableMutationObserver = function () { + if (mutationObserverEnabled) { + return; + } + var mutationHandler = function (mutationsList) { + var addedNodes; + for (var i = 0, mutation; (mutation = mutationsList[i]) !== undefined; i++) { + if (mutation.type === 'childList') { + addedNodes = mutation.addedNodes; + for (var j = 0, addedNode; (addedNode = addedNodes[j]) !== undefined; j++) { + renderNodeAndChildren(addedNode); + } + } + } + }; + var MutationObserver = globals.getKeyValue('MutationObserver'); + if (MutationObserver) { + globalMutationObserver = new MutationObserver(mutationHandler); + globalMutationObserver.observe(getGlobal().document.documentElement, { + childList: true, + subtree: true + }); + mutationObserverEnabled = true; + } + }; + var renderTagsInDocument = function (tagName) { + var nodes = getGlobal().document.getElementsByTagName(tagName); + for (var i = 0, node; (node = nodes[i]) !== undefined; i++) { + mountElement(node); + } + }; + var attr = function (attributeName, attrHandler) { + if (attrHandler) { + if (typeof attributeName === 'string') { + attributes[attributeName] = attrHandler; + } else { + regExpAttributes.push({ + match: attributeName, + handler: attrHandler + }); + } + } else { + var cb = attributes[attributeName]; + if (!cb) { + for (var i = 0, len = regExpAttributes.length; i < len; i++) { + var attrMatcher = regExpAttributes[i]; + if (attrMatcher.match.test(attributeName)) { + return attrMatcher.handler; + } + } + } + return cb; + } + }; + var attrs = function (attrMap) { + var map = canReflect.getKeyValue(attrMap, callbackMapSymbol) || attrMap; + if (attrMaps.has(map)) { + return; + } else { + attrMaps.set(map, true); + } + canReflect.eachKey(map, function (callback, exp) { + attr(exp, callback); + }); + }; + var attributes = {}, regExpAttributes = [], attrMaps = new WeakMap(), automaticCustomElementCharacters = /[-\:]/; + var defaultCallback = function () { + }; + var tag = function (tagName, tagHandler) { + if (tagHandler) { + var GLOBAL = getGlobal(); + var validCustomElementName = automaticCustomElementCharacters.test(tagName), tagExists = typeof tags[tagName.toLowerCase()] !== 'undefined', customElementExists; + if (GLOBAL.html5) { + GLOBAL.html5.elements += ' ' + tagName; + GLOBAL.html5.shivDocument(); + } + tags[tagName.toLowerCase()] = tagHandler; + if (automountEnabled()) { + var customElements = globals.getKeyValue('customElements'); + if (customElements) { + customElementExists = customElements.get(tagName.toLowerCase()); + if (validCustomElementName && !customElementExists) { + var CustomElement = function () { + return Reflect.construct(HTMLElement, [], CustomElement); + }; + CustomElement.prototype = Object.create(HTMLElement.prototype); + CustomElement.prototype.connectedCallback = function () { + callbacks.tagHandler(this, tagName.toLowerCase(), {}); + }; + customElements.define(tagName, CustomElement); + } + } else { + enableMutationObserver(); + renderTagsInDocument(tagName); + } + } else if (mutationObserverEnabled) { + globalMutationObserver.disconnect(); + } + } else { + var cb; + if (tagHandler === null) { + delete tags[tagName.toLowerCase()]; + } else { + cb = tags[tagName.toLowerCase()]; + } + if (!cb && automaticCustomElementCharacters.test(tagName)) { + cb = defaultCallback; + } + return cb; + } + }; + var callbacks = { + _tags: tags, + _attributes: attributes, + _regExpAttributes: regExpAttributes, + defaultCallback: defaultCallback, + tag: tag, + attr: attr, + attrs: attrs, + tagHandler: function (el, tagName, tagData) { + if (renderedElements.has(el)) { + return; + } + var scope = tagData.scope, helperTagCallback = scope && scope.templateContext.tags.get(tagName), tagCallback = helperTagCallback || tags[tagName], res; + if (tagCallback) { + res = ObservationRecorder.ignore(tagCallback)(el, tagData); + renderedElements.set(el, true); + } else { + res = scope; + } + if (res && tagData.subtemplate) { + if (scope !== res) { + scope = scope.add(res); + } + var nodeList = nodeLists.register([], undefined, tagData.parentNodeList || true, false); + nodeList.expression = '<' + el.tagName + '>'; + var result = tagData.subtemplate(scope, tagData.options, nodeList); + var frag = typeof result === 'string' ? makeFrag(result) : result; + domMutate.appendChild.call(el, frag); + } + } + }; + namespace.view = namespace.view || {}; + if (namespace.view.callbacks) { + throw new Error('You can\'t have two versions of can-view-callbacks, check your dependencies'); + } else { + module.exports = namespace.view.callbacks = callbacks; + } + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-view-target@4.1.2#can-view-target*/ +define('can-view-target@4.1.2#can-view-target', [ + 'require', + 'exports', + 'module', + 'can-globals/document/document', + 'can-dom-mutate/node', + 'can-namespace', + 'can-globals/mutation-observer/mutation-observer' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var getDocument = require('can-globals/document/document'); + var domMutate = require('can-dom-mutate/node'); + var namespace = require('can-namespace'); + var MUTATION_OBSERVER = require('can-globals/mutation-observer/mutation-observer'); + var processNodes = function (nodes, paths, location, document) { + var frag = document.createDocumentFragment(); + for (var i = 0, len = nodes.length; i < len; i++) { + var node = nodes[i]; + frag.appendChild(processNode(node, paths, location.concat(i), document)); + } + return frag; + }, keepsTextNodes = typeof document !== 'undefined' && function () { + var testFrag = document.createDocumentFragment(); + var div = document.createElement('div'); + div.appendChild(document.createTextNode('')); + div.appendChild(document.createTextNode('')); + testFrag.appendChild(div); + var cloned = testFrag.cloneNode(true); + return cloned.firstChild.childNodes.length === 2; + }(), clonesWork = typeof document !== 'undefined' && function () { + var el = document.createElement('a'); + el.innerHTML = ''; + var clone = el.cloneNode(true); + var works = clone.innerHTML === ''; + var MO, observer; + if (works) { + el = document.createDocumentFragment(); + el.appendChild(document.createTextNode('foo-bar')); + MO = MUTATION_OBSERVER(); + if (MO) { + observer = new MO(function () { + }); + observer.observe(document.documentElement, { + childList: true, + subtree: true + }); + clone = el.cloneNode(true); + observer.disconnect(); + } else { + clone = el.cloneNode(true); + } + return clone.childNodes.length === 1; + } + return works; + }(), namespacesWork = typeof document !== 'undefined' && !!document.createElementNS; + var cloneNode = clonesWork ? function (el) { + return el.cloneNode(true); + } : function (node) { + var document = node.ownerDocument; + var copy; + if (node.nodeType === 1) { + if (node.namespaceURI !== 'http://www.w3.org/1999/xhtml' && namespacesWork && document.createElementNS) { + copy = document.createElementNS(node.namespaceURI, node.nodeName); + } else { + copy = document.createElement(node.nodeName); + } + } else if (node.nodeType === 3) { + copy = document.createTextNode(node.nodeValue); + } else if (node.nodeType === 8) { + copy = document.createComment(node.nodeValue); + } else if (node.nodeType === 11) { + copy = document.createDocumentFragment(); + } + if (node.attributes) { + var attributes = node.attributes; + for (var i = 0; i < attributes.length; i++) { + var attribute = attributes[i]; + if (attribute && attribute.specified) { + if (attribute.namespaceURI) { + copy.setAttributeNS(attribute.namespaceURI, attribute.nodeName || attribute.name, attribute.nodeValue || attribute.value); + } else { + copy.setAttribute(attribute.nodeName || attribute.name, attribute.nodeValue || attribute.value); + } + } + } + } + if (node && node.firstChild) { + var child = node.firstChild; + while (child) { + copy.appendChild(cloneNode(child)); + child = child.nextSibling; + } + } + return copy; + }; + function processNode(node, paths, location, document) { + var callback, loc = location, nodeType = typeof node, el, p, i, len; + var getCallback = function () { + if (!callback) { + callback = { + path: location, + callbacks: [] + }; + paths.push(callback); + loc = []; + } + return callback; + }; + if (nodeType === 'object') { + if (node.tag) { + if (namespacesWork && node.namespace) { + el = document.createElementNS(node.namespace, node.tag); + } else { + el = document.createElement(node.tag); + } + if (node.attrs) { + for (var attrName in node.attrs) { + var value = node.attrs[attrName]; + if (typeof value === 'function') { + getCallback().callbacks.push({ callback: value }); + } else if (value !== null && typeof value === 'object' && value.namespaceURI) { + el.setAttributeNS(value.namespaceURI, attrName, value.value); + } else { + domMutate.setAttribute.call(el, attrName, value); + } + } + } + if (node.attributes) { + for (i = 0, len = node.attributes.length; i < len; i++) { + getCallback().callbacks.push({ callback: node.attributes[i] }); + } + } + if (node.children && node.children.length) { + if (callback) { + p = callback.paths = []; + } else { + p = paths; + } + el.appendChild(processNodes(node.children, p, loc, document)); + } + } else if (node.comment) { + el = document.createComment(node.comment); + if (node.callbacks) { + for (i = 0, len = node.attributes.length; i < len; i++) { + getCallback().callbacks.push({ callback: node.callbacks[i] }); + } + } + } + } else if (nodeType === 'string') { + el = document.createTextNode(node); + } else if (nodeType === 'function') { + if (keepsTextNodes) { + el = document.createTextNode(''); + getCallback().callbacks.push({ callback: node }); + } else { + el = document.createComment('~'); + getCallback().callbacks.push({ + callback: function () { + var el = document.createTextNode(''); + domMutate.replaceChild.call(this.parentNode, el, this); + return node.apply(el, arguments); + } + }); + } + } + return el; + } + function getCallbacks(el, pathData, elementCallbacks) { + var path = pathData.path, callbacks = pathData.callbacks, paths = pathData.paths, child = el, pathLength = path ? path.length : 0, pathsLength = paths ? paths.length : 0; + for (var i = 0; i < pathLength; i++) { + child = child.childNodes.item(path[i]); + } + for (i = 0; i < pathsLength; i++) { + getCallbacks(child, paths[i], elementCallbacks); + } + elementCallbacks.push({ + element: child, + callbacks: callbacks + }); + } + function hydrateCallbacks(callbacks, args) { + var len = callbacks.length, callbacksLength, callbackElement, callbackData; + for (var i = 0; i < len; i++) { + callbackData = callbacks[i]; + callbacksLength = callbackData.callbacks.length; + callbackElement = callbackData.element; + for (var c = 0; c < callbacksLength; c++) { + callbackData.callbacks[c].callback.apply(callbackElement, args); + } + } + } + function makeTarget(nodes, doc) { + var paths = []; + var frag = processNodes(nodes, paths, [], doc || getDocument()); + return { + paths: paths, + clone: frag, + hydrate: function () { + var cloned = cloneNode(this.clone); + var args = []; + for (var a = 0, ref = args.length = arguments.length; a < ref; a++) { + args[a] = arguments[a]; + } + var callbacks = []; + for (var i = 0; i < paths.length; i++) { + getCallbacks(cloned, paths[i], callbacks); + } + hydrateCallbacks(callbacks, args); + return cloned; + } + }; + } + makeTarget.keepsTextNodes = keepsTextNodes; + makeTarget.cloneNode = cloneNode; + namespace.view = namespace.view || {}; + module.exports = namespace.view.target = makeTarget; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-reflect-promise@2.2.0#can-reflect-promise*/ +define('can-reflect-promise@2.2.0#can-reflect-promise', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-symbol', + 'can-observation-recorder', + 'can-queues', + 'can-key-tree', + 'can-log/dev/dev' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var ObservationRecorder = require('can-observation-recorder'); + var queues = require('can-queues'); + var KeyTree = require('can-key-tree'); + var dev = require('can-log/dev/dev'); + var getKeyValueSymbol = canSymbol.for('can.getKeyValue'), observeDataSymbol = canSymbol.for('can.meta'); + var promiseDataPrototype = { + isPending: true, + state: 'pending', + isResolved: false, + isRejected: false, + value: undefined, + reason: undefined + }; + function setVirtualProp(promise, property, value) { + var observeData = promise[observeDataSymbol]; + var old = observeData[property]; + observeData[property] = value; + queues.enqueueByQueue(observeData.handlers.getNode([property]), promise, [ + value, + old + ], function () { + return {}; + }, [ + 'Promise', + promise, + 'resolved with value', + value, + 'and changed virtual property: ' + property + ]); + } + function initPromise(promise) { + var observeData = promise[observeDataSymbol]; + if (!observeData) { + Object.defineProperty(promise, observeDataSymbol, { + enumerable: false, + configurable: false, + writable: false, + value: Object.create(promiseDataPrototype) + }); + observeData = promise[observeDataSymbol]; + observeData.handlers = new KeyTree([ + Object, + Object, + Array + ]); + } + promise.then(function (value) { + queues.batch.start(); + setVirtualProp(promise, 'isPending', false); + setVirtualProp(promise, 'isResolved', true); + setVirtualProp(promise, 'value', value); + setVirtualProp(promise, 'state', 'resolved'); + queues.batch.stop(); + }, function (reason) { + queues.batch.start(); + setVirtualProp(promise, 'isPending', false); + setVirtualProp(promise, 'isRejected', true); + setVirtualProp(promise, 'reason', reason); + setVirtualProp(promise, 'state', 'rejected'); + queues.batch.stop(); + }); + } + function setupPromise(value) { + var oldPromiseFn; + var proto = 'getPrototypeOf' in Object ? Object.getPrototypeOf(value) : value.__proto__; + if (value[getKeyValueSymbol] && value[observeDataSymbol]) { + return; + } + if (proto === null || proto === Object.prototype) { + proto = value; + if (typeof proto.promise === 'function') { + oldPromiseFn = proto.promise; + proto.promise = function () { + var result = oldPromiseFn.call(proto); + setupPromise(result); + return result; + }; + } + } + canReflect.assignSymbols(proto, { + 'can.getKeyValue': function (key) { + if (!this[observeDataSymbol]) { + initPromise(this); + } + ObservationRecorder.add(this, key); + switch (key) { + case 'state': + case 'isPending': + case 'isResolved': + case 'isRejected': + case 'value': + case 'reason': + return this[observeDataSymbol][key]; + default: + return this[key]; + } + }, + 'can.getValue': function () { + return this[getKeyValueSymbol]('value'); + }, + 'can.isValueLike': false, + 'can.onKeyValue': function (key, handler, queue) { + if (!this[observeDataSymbol]) { + initPromise(this); + } + this[observeDataSymbol].handlers.add([ + key, + queue || 'mutate', + handler + ]); + }, + 'can.offKeyValue': function (key, handler, queue) { + if (!this[observeDataSymbol]) { + initPromise(this); + } + this[observeDataSymbol].handlers.delete([ + key, + queue || 'mutate', + handler + ]); + }, + 'can.hasOwnKey': function (key) { + if (!this[observeDataSymbol]) { + initPromise(this); + } + return key in this[observeDataSymbol]; + } + }); + } + module.exports = setupPromise; +}); +/*can-stache-key@1.4.0#can-stache-key*/ +define('can-stache-key@1.4.0#can-stache-key', [ + 'require', + 'exports', + 'module', + 'can-observation-recorder', + 'can-log/dev/dev', + 'can-symbol', + 'can-reflect', + 'can-reflect-promise' +], function (require, exports, module) { + 'use strict'; + var ObservationRecorder = require('can-observation-recorder'); + var dev = require('can-log/dev/dev'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + var canReflectPromise = require('can-reflect-promise'); + var getValueSymbol = canSymbol.for('can.getValue'); + var setValueSymbol = canSymbol.for('can.setValue'); + var isValueLikeSymbol = canSymbol.for('can.isValueLike'); + var peek = ObservationRecorder.ignore(canReflect.getKeyValue.bind(canReflect)); + var observeReader; + var bindName = Function.prototype.bind; + var isAt = function (index, reads) { + var prevRead = reads[index - 1]; + return prevRead && prevRead.at; + }; + var readValue = function (value, index, reads, options, state, prev) { + var usedValueReader; + do { + usedValueReader = false; + for (var i = 0, len = observeReader.valueReaders.length; i < len; i++) { + if (observeReader.valueReaders[i].test(value, index, reads, options)) { + value = observeReader.valueReaders[i].read(value, index, reads, options, state, prev); + } + } + } while (usedValueReader); + return value; + }; + var specialRead = { + index: true, + key: true, + event: true, + element: true, + viewModel: true + }; + var checkForObservableAndNotify = function (options, state, getObserves, value, index) { + if (options.foundObservable && !state.foundObservable) { + if (ObservationRecorder.trapsCount()) { + ObservationRecorder.addMany(getObserves()); + options.foundObservable(value, index); + state.foundObservable = true; + } + } + }; + var objHasKeyAtIndex = function (obj, reads, index) { + return !!(reads && reads.length && canReflect.hasKey(obj, reads[index].key)); + }; + observeReader = { + read: function (parent, reads, options) { + options = options || {}; + var state = { foundObservable: false }; + var getObserves; + if (options.foundObservable) { + getObserves = ObservationRecorder.trap(); + } + var cur = readValue(parent, 0, reads, options, state), type, prev, readLength = reads.length, i = 0, last, parentHasKey; + checkForObservableAndNotify(options, state, getObserves, parent, 0); + while (i < readLength) { + prev = cur; + for (var r = 0, readersLength = observeReader.propertyReaders.length; r < readersLength; r++) { + var reader = observeReader.propertyReaders[r]; + if (reader.test(cur)) { + cur = reader.read(cur, reads[i], i, options, state); + break; + } + } + checkForObservableAndNotify(options, state, getObserves, prev, i); + last = cur; + i = i + 1; + cur = readValue(cur, i, reads, options, state, prev); + checkForObservableAndNotify(options, state, getObserves, prev, i - 1); + type = typeof cur; + if (i < reads.length && (cur === null || cur === undefined)) { + parentHasKey = objHasKeyAtIndex(prev, reads, i - 1); + if (options.earlyExit && !parentHasKey) { + options.earlyExit(prev, i - 1, cur); + } + return { + value: undefined, + parent: prev, + parentHasKey: parentHasKey, + foundLastParent: false + }; + } + } + parentHasKey = objHasKeyAtIndex(prev, reads, reads.length - 1); + if (cur === undefined && !parentHasKey) { + if (options.earlyExit) { + options.earlyExit(prev, i - 1); + } + } + return { + value: cur, + parent: prev, + parentHasKey: parentHasKey, + foundLastParent: true + }; + }, + get: function (parent, reads, options) { + return observeReader.read(parent, observeReader.reads(reads), options || {}).value; + }, + valueReadersMap: {}, + valueReaders: [ + { + name: 'function', + test: function (value) { + return value && canReflect.isFunctionLike(value) && !canReflect.isConstructorLike(value); + }, + read: function (value, i, reads, options, state, prev) { + if (options.callMethodsOnObservables && canReflect.isObservableLike(prev) && canReflect.isMapLike(prev)) { + dev.warn('can-stache-key: read() called with `callMethodsOnObservables: true`.'); + return value.apply(prev, options.args || []); + } + return options.proxyMethods !== false ? bindName.call(value, prev) : value; + } + }, + { + name: 'isValueLike', + test: function (value, i, reads, options) { + return value && value[getValueSymbol] && value[isValueLikeSymbol] !== false && (options.foundAt || !isAt(i, reads)); + }, + read: function (value, i, reads, options) { + if (options.readCompute === false && i === reads.length) { + return value; + } + return canReflect.getValue(value); + }, + write: function (base, newVal) { + if (base[setValueSymbol]) { + base[setValueSymbol](newVal); + } else if (base.set) { + base.set(newVal); + } else { + base(newVal); + } + } + } + ], + propertyReadersMap: {}, + propertyReaders: [ + { + name: 'map', + test: function (value) { + if (canReflect.isPromise(value) || typeof value === 'object' && value && typeof value.then === 'function') { + canReflectPromise(value); + } + return canReflect.isObservableLike(value) && canReflect.isMapLike(value); + }, + read: function (value, prop) { + var res = canReflect.getKeyValue(value, prop.key); + if (res !== undefined) { + return res; + } else { + return value[prop.key]; + } + }, + write: canReflect.setKeyValue + }, + { + name: 'object', + test: function () { + return true; + }, + read: function (value, prop, i, options) { + if (value == null) { + return undefined; + } else { + if (typeof value === 'object') { + if (prop.key in value) { + return value[prop.key]; + } + } else { + return value[prop.key]; + } + } + }, + write: function (base, prop, newVal) { + var propValue = base[prop]; + if (newVal != null && typeof newVal === 'object' && canReflect.isMapLike(propValue)) { + dev.warn('can-stache-key: Merging data into "' + prop + '" because its parent is non-observable'); + canReflect.update(propValue, newVal); + } else if (propValue != null && propValue[setValueSymbol] !== undefined) { + canReflect.setValue(propValue, newVal); + } else { + base[prop] = newVal; + } + } + } + ], + reads: function (keyArg) { + var key = '' + keyArg; + var keys = []; + var last = 0; + var at = false; + if (key.charAt(0) === '@') { + last = 1; + at = true; + } + var keyToAdd = ''; + for (var i = last; i < key.length; i++) { + var character = key.charAt(i); + if (character === '.' || character === '@') { + if (key.charAt(i - 1) !== '\\') { + keys.push({ + key: keyToAdd, + at: at + }); + at = character === '@'; + keyToAdd = ''; + } else { + keyToAdd = keyToAdd.substr(0, keyToAdd.length - 1) + '.'; + } + } else { + keyToAdd += character; + } + } + keys.push({ + key: keyToAdd, + at: at + }); + return keys; + }, + write: function (parent, key, value, options) { + var keys = typeof key === 'string' ? observeReader.reads(key) : key; + var last; + options = options || {}; + if (keys.length > 1) { + last = keys.pop(); + parent = observeReader.read(parent, keys, options).value; + keys.push(last); + } else { + last = keys[0]; + } + if (!parent) { + return; + } + var keyValue = peek(parent, last.key); + if (observeReader.valueReadersMap.isValueLike.test(keyValue, keys.length - 1, keys, options)) { + observeReader.valueReadersMap.isValueLike.write(keyValue, value, options); + } else { + if (observeReader.valueReadersMap.isValueLike.test(parent, keys.length - 1, keys, options)) { + parent = parent[getValueSymbol](); + } + if (observeReader.propertyReadersMap.map.test(parent)) { + observeReader.propertyReadersMap.map.write(parent, last.key, value, options); + } else if (observeReader.propertyReadersMap.object.test(parent)) { + observeReader.propertyReadersMap.object.write(parent, last.key, value, options); + if (options.observation) { + options.observation.update(); + } + } + } + } + }; + observeReader.propertyReaders.forEach(function (reader) { + observeReader.propertyReadersMap[reader.name] = reader; + }); + observeReader.valueReaders.forEach(function (reader) { + observeReader.valueReadersMap[reader.name] = reader; + }); + observeReader.set = observeReader.write; + module.exports = observeReader; +}); +/*can-view-scope@4.11.1#template-context*/ +define('can-view-scope@4.11.1#template-context', [ + 'require', + 'exports', + 'module', + 'can-simple-map' +], function (require, exports, module) { + 'use strict'; + var SimpleMap = require('can-simple-map'); + var TemplateContext = function (options) { + options = options || {}; + this.vars = new SimpleMap(options.vars || {}); + this.helpers = new SimpleMap(options.helpers || {}); + this.partials = new SimpleMap(options.partials || {}); + this.tags = new SimpleMap(options.tags || {}); + }; + module.exports = TemplateContext; +}); +/*can-define-lazy-value@1.1.0#define-lazy-value*/ +define('can-define-lazy-value@1.1.0#define-lazy-value', function (require, exports, module) { + 'use strict'; + module.exports = function defineLazyValue(obj, prop, initializer, writable) { + Object.defineProperty(obj, prop, { + configurable: true, + get: function () { + Object.defineProperty(this, prop, { + value: undefined, + writable: true + }); + var value = initializer.call(this, obj, prop); + Object.defineProperty(this, prop, { + value: value, + writable: !!writable + }); + return value; + }, + set: function (value) { + Object.defineProperty(this, prop, { + value: value, + writable: !!writable + }); + return value; + } + }); + }; +}); +/*can-event-queue@1.1.3#value/value*/ +define('can-event-queue@1.1.3#value/value', [ + 'require', + 'exports', + 'module', + 'can-queues', + 'can-key-tree', + 'can-reflect', + 'can-define-lazy-value', + '../dependency-record/merge' +], function (require, exports, module) { + 'use strict'; + var queues = require('can-queues'); + var KeyTree = require('can-key-tree'); + var canReflect = require('can-reflect'); + var defineLazyValue = require('can-define-lazy-value'); + var mergeDependencyRecords = require('../dependency-record/merge'); + var properties = { + on: function (handler, queue) { + this.handlers.add([ + queue || 'mutate', + handler + ]); + }, + off: function (handler, queueName) { + if (handler === undefined) { + if (queueName === undefined) { + this.handlers.delete([]); + } else { + this.handlers.delete([queueName]); + } + } else { + this.handlers.delete([ + queueName || 'mutate', + handler + ]); + } + } + }; + var symbols = { + 'can.onValue': properties.on, + 'can.offValue': properties.off, + 'can.dispatch': function (value, old) { + var queuesArgs = []; + queuesArgs = [ + this.handlers.getNode([]), + this, + [ + value, + old + ] + ]; + queues.enqueueByQueue.apply(queues, queuesArgs); + }, + 'can.getWhatIChange': function getWhatIChange() { + }, + 'can.isBound': function isBound() { + return !this.handlers.isEmpty(); + } + }; + function defineLazyHandlers() { + return new KeyTree([ + Object, + Array + ], { + onFirst: this.onBound !== undefined && this.onBound.bind(this), + onEmpty: this.onUnbound !== undefined && this.onUnbound.bind(this) + }); + } + var mixinValueEventBindings = function (obj) { + canReflect.assign(obj, properties); + canReflect.assignSymbols(obj, symbols); + defineLazyValue(obj, 'handlers', defineLazyHandlers, true); + return obj; + }; + mixinValueEventBindings.addHandlers = function (obj, callbacks) { + console.warn('can-event-queue/value: Avoid using addHandlers. Add onBound and onUnbound methods instead.'); + obj.handlers = new KeyTree([ + Object, + Array + ], callbacks); + return obj; + }; + module.exports = mixinValueEventBindings; +}); +/*can-observation@4.1.1#recorder-dependency-helpers*/ +define('can-observation@4.1.1#recorder-dependency-helpers', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + function addNewKeyDependenciesIfNotInOld(event) { + if (this.oldEventSet === undefined || this.oldEventSet['delete'](event) === false) { + canReflect.onKeyValue(this.observable, event, this.onDependencyChange, 'notify'); + } + } + function addObservablesNewKeyDependenciesIfNotInOld(eventSet, observable) { + eventSet.forEach(addNewKeyDependenciesIfNotInOld, { + onDependencyChange: this.onDependencyChange, + observable: observable, + oldEventSet: this.oldDependencies.keyDependencies.get(observable) + }); + } + function removeKeyDependencies(event) { + canReflect.offKeyValue(this.observable, event, this.onDependencyChange, 'notify'); + } + function removeObservablesKeyDependencies(oldEventSet, observable) { + oldEventSet.forEach(removeKeyDependencies, { + onDependencyChange: this.onDependencyChange, + observable: observable + }); + } + function addValueDependencies(observable) { + if (this.oldDependencies.valueDependencies.delete(observable) === false) { + canReflect.onValue(observable, this.onDependencyChange, 'notify'); + } + } + function removeValueDependencies(observable) { + canReflect.offValue(observable, this.onDependencyChange, 'notify'); + } + module.exports = { + updateObservations: function (observationData) { + observationData.newDependencies.keyDependencies.forEach(addObservablesNewKeyDependenciesIfNotInOld, observationData); + observationData.oldDependencies.keyDependencies.forEach(removeObservablesKeyDependencies, observationData); + observationData.newDependencies.valueDependencies.forEach(addValueDependencies, observationData); + observationData.oldDependencies.valueDependencies.forEach(removeValueDependencies, observationData); + }, + stopObserving: function (observationReciever, onDependencyChange) { + observationReciever.keyDependencies.forEach(removeObservablesKeyDependencies, { onDependencyChange: onDependencyChange }); + observationReciever.valueDependencies.forEach(removeValueDependencies, { onDependencyChange: onDependencyChange }); + } + }; +}); +/*can-observation@4.1.1#temporarily-bind*/ +define('can-observation@4.1.1#temporarily-bind', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var temporarilyBoundNoOperation = function () { + }; + var observables; + var unbindTemporarilyBoundValue = function () { + for (var i = 0, len = observables.length; i < len; i++) { + canReflect.offValue(observables[i], temporarilyBoundNoOperation); + } + observables = null; + }; + function temporarilyBind(compute) { + var computeInstance = compute.computeInstance || compute; + canReflect.onValue(computeInstance, temporarilyBoundNoOperation); + if (!observables) { + observables = []; + setTimeout(unbindTemporarilyBoundValue, 10); + } + observables.push(computeInstance); + } + module.exports = temporarilyBind; +}); +/*can-observation@4.1.1#can-observation*/ +define('can-observation@4.1.1#can-observation', [ + 'require', + 'exports', + 'module', + 'can-namespace', + 'can-reflect', + 'can-queues', + 'can-observation-recorder', + 'can-symbol', + 'can-log/dev/dev', + 'can-event-queue/value/value', + './recorder-dependency-helpers', + './temporarily-bind' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + var canReflect = require('can-reflect'); + var queues = require('can-queues'); + var ObservationRecorder = require('can-observation-recorder'); + var canSymbol = require('can-symbol'); + var dev = require('can-log/dev/dev'); + var valueEventBindings = require('can-event-queue/value/value'); + var recorderHelpers = require('./recorder-dependency-helpers'); + var temporarilyBind = require('./temporarily-bind'); + var dispatchSymbol = canSymbol.for('can.dispatch'); + var getChangesSymbol = canSymbol.for('can.getChangesDependencyRecord'); + var getValueDependenciesSymbol = canSymbol.for('can.getValueDependencies'); + function Observation(func, context, options) { + this.func = func; + this.context = context; + this.options = options || { + priority: 0, + isObservable: true + }; + this.bound = false; + this._value = undefined; + this.newDependencies = ObservationRecorder.makeDependenciesRecord(); + this.oldDependencies = null; + var self = this; + this.onDependencyChange = function (newVal) { + self.dependencyChange(this, newVal); + }; + this.update = this.update.bind(this); + } + valueEventBindings(Observation.prototype); + canReflect.assign(Observation.prototype, { + onBound: function () { + this.bound = true; + this.oldDependencies = this.newDependencies; + ObservationRecorder.start(); + this._value = this.func.call(this.context); + this.newDependencies = ObservationRecorder.stop(); + recorderHelpers.updateObservations(this); + }, + dependencyChange: function (context, args) { + if (this.bound === true) { + var queuesArgs = []; + queuesArgs = [ + this.update, + this, + [], + { priority: this.options.priority } + ]; + queues.deriveQueue.enqueue.apply(queues.deriveQueue, queuesArgs); + } + }, + update: function () { + if (this.bound === true) { + var oldValue = this._value; + this.oldValue = null; + this.onBound(); + if (oldValue !== this._value) { + this[dispatchSymbol](this._value, oldValue); + } + } + }, + onUnbound: function () { + this.bound = false; + recorderHelpers.stopObserving(this.newDependencies, this.onDependencyChange); + this.newDependencies = ObservationRecorder.makeDependenciesRecorder(); + }, + get: function () { + if (this.options.isObservable && ObservationRecorder.isRecording()) { + ObservationRecorder.add(this); + if (!this.bound) { + Observation.temporarilyBind(this); + } + } + if (this.bound === true) { + if (queues.deriveQueue.tasksRemainingCount() > 0) { + Observation.updateChildrenAndSelf(this); + } + return this._value; + } else { + return this.func.call(this.context); + } + }, + hasDependencies: function () { + var newDependencies = this.newDependencies; + return this.bound ? newDependencies.valueDependencies.size + newDependencies.keyDependencies.size > 0 : undefined; + }, + log: function () { + } + }); + Object.defineProperty(Observation.prototype, 'value', { + get: function () { + return this.get(); + } + }); + var observationProto = { + 'can.getValue': Observation.prototype.get, + 'can.isValueLike': true, + 'can.isMapLike': false, + 'can.isListLike': false, + 'can.valueHasDependencies': Observation.prototype.hasDependencies, + 'can.getValueDependencies': function () { + if (this.bound === true) { + var deps = this.newDependencies, result = {}; + if (deps.keyDependencies.size) { + result.keyDependencies = deps.keyDependencies; + } + if (deps.valueDependencies.size) { + result.valueDependencies = deps.valueDependencies; + } + return result; + } + return undefined; + }, + 'can.getPriority': function () { + return this.options.priority; + }, + 'can.setPriority': function (priority) { + this.options.priority = priority; + } + }; + canReflect.assignSymbols(Observation.prototype, observationProto); + Observation.updateChildrenAndSelf = function (observation) { + if (observation.update !== undefined && queues.deriveQueue.isEnqueued(observation.update) === true) { + queues.deriveQueue.flushQueuedTask(observation.update); + return true; + } + if (observation[getValueDependenciesSymbol]) { + var childHasChanged = false; + var valueDependencies = observation[getValueDependenciesSymbol]().valueDependencies || []; + valueDependencies.forEach(function (observable) { + if (Observation.updateChildrenAndSelf(observable) === true) { + childHasChanged = true; + } + }); + return childHasChanged; + } else { + return false; + } + }; + var alias = { addAll: 'addMany' }; + [ + 'add', + 'addAll', + 'ignore', + 'trap', + 'trapsCount', + 'isRecording' + ].forEach(function (methodName) { + Observation[methodName] = function () { + var name = alias[methodName] ? alias[methodName] : methodName; + console.warn('can-observation: Call ' + name + '() on can-observation-recorder.'); + return ObservationRecorder[name].apply(this, arguments); + }; + }); + Observation.prototype.start = function () { + console.warn('can-observation: Use .on and .off to bind.'); + return this.onBound(); + }; + Observation.prototype.stop = function () { + console.warn('can-observation: Use .on and .off to bind.'); + return this.onUnbound(); + }; + Observation.temporarilyBind = temporarilyBind; + module.exports = namespace.Observation = Observation; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-cid@1.3.0#can-cid*/ +define('can-cid@1.3.0#can-cid', [ + 'require', + 'exports', + 'module', + 'can-namespace' +], function (require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + var _cid = 0; + var domExpando = 'can' + new Date(); + var cid = function (object, name) { + var propertyName = object.nodeName ? domExpando : '_cid'; + if (!object[propertyName]) { + _cid++; + object[propertyName] = (name || '') + _cid; + } + return object[propertyName]; + }; + cid.domExpando = domExpando; + cid.get = function (object) { + var type = typeof object; + var isObject = type !== null && (type === 'object' || type === 'function'); + return isObject ? cid(object) : type + ':' + object; + }; + if (namespace.cid) { + throw new Error('You can\'t have two versions of can-cid, check your dependencies'); + } else { + module.exports = namespace.cid = cid; + } +}); +/*can-single-reference@1.2.0#can-single-reference*/ +define('can-single-reference@1.2.0#can-single-reference', [ + 'require', + 'exports', + 'module', + 'can-cid' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var CID = require('can-cid'); + var singleReference; + function getKeyName(key, extraKey) { + var keyName = extraKey ? CID(key) + ':' + extraKey : CID(key); + return keyName || key; + } + singleReference = { + set: function (obj, key, value, extraKey) { + obj[getKeyName(key, extraKey)] = value; + }, + getAndDelete: function (obj, key, extraKey) { + var keyName = getKeyName(key, extraKey); + var value = obj[keyName]; + delete obj[keyName]; + return value; + } + }; + module.exports = singleReference; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-view-scope@4.11.1#make-compute-like*/ +define('can-view-scope@4.11.1#make-compute-like', [ + 'require', + 'exports', + 'module', + 'can-single-reference', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var singleReference = require('can-single-reference'); + var canReflect = require('can-reflect'); + var Compute = function (newVal) { + if (arguments.length) { + return canReflect.setValue(this, newVal); + } else { + return canReflect.getValue(this); + } + }; + module.exports = function (observable) { + var compute = Compute.bind(observable); + compute.on = compute.bind = compute.addEventListener = function (event, handler) { + var translationHandler = function (newVal, oldVal) { + handler.call(compute, { type: 'change' }, newVal, oldVal); + }; + singleReference.set(handler, this, translationHandler); + observable.on(translationHandler); + }; + compute.off = compute.unbind = compute.removeEventListener = function (event, handler) { + observable.off(singleReference.getAndDelete(handler, this)); + }; + canReflect.assignSymbols(compute, { + 'can.getValue': function () { + return canReflect.getValue(observable); + }, + 'can.setValue': function (newVal) { + return canReflect.setValue(observable, newVal); + }, + 'can.onValue': function (handler, queue) { + return canReflect.onValue(observable, handler, queue); + }, + 'can.offValue': function (handler, queue) { + return canReflect.offValue(observable, handler, queue); + }, + 'can.valueHasDependencies': function () { + return canReflect.valueHasDependencies(observable); + }, + 'can.getPriority': function () { + return canReflect.getPriority(observable); + }, + 'can.setPriority': function (newPriority) { + canReflect.setPriority(observable, newPriority); + }, + 'can.isValueLike': true, + 'can.isFunctionLike': false + }); + compute.isComputed = true; + return compute; + }; +}); +/*can-reflect-dependencies@1.1.1#src/add-mutated-by*/ +define('can-reflect-dependencies@1.1.1#src/add-mutated-by', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var makeDependencyRecord = function makeDependencyRecord() { + return { + keyDependencies: new Map(), + valueDependencies: new Set() + }; + }; + var makeRootRecord = function makeRootRecord() { + return { + mutateDependenciesForKey: new Map(), + mutateDependenciesForValue: makeDependencyRecord() + }; + }; + module.exports = function (mutatedByMap) { + return function addMutatedBy(mutated, key, mutator) { + var gotKey = arguments.length === 3; + if (arguments.length === 2) { + mutator = key; + key = undefined; + } + if (!mutator.keyDependencies && !mutator.valueDependencies) { + var s = new Set(); + s.add(mutator); + mutator = { valueDependencies: s }; + } + var root = mutatedByMap.get(mutated); + if (!root) { + root = makeRootRecord(); + mutatedByMap.set(mutated, root); + } + if (gotKey && !root.mutateDependenciesForKey.get(key)) { + root.mutateDependenciesForKey.set(key, makeDependencyRecord()); + } + var dependencyRecord = gotKey ? root.mutateDependenciesForKey.get(key) : root.mutateDependenciesForValue; + if (mutator.valueDependencies) { + canReflect.addValues(dependencyRecord.valueDependencies, mutator.valueDependencies); + } + if (mutator.keyDependencies) { + canReflect.each(mutator.keyDependencies, function (keysSet, obj) { + var entry = dependencyRecord.keyDependencies.get(obj); + if (!entry) { + entry = new Set(); + dependencyRecord.keyDependencies.set(obj, entry); + } + canReflect.addValues(entry, keysSet); + }); + } + }; + }; +}); +/*can-reflect-dependencies@1.1.1#src/delete-mutated-by*/ +define('can-reflect-dependencies@1.1.1#src/delete-mutated-by', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + module.exports = function (mutatedByMap) { + return function deleteMutatedBy(mutated, key, mutator) { + var gotKey = arguments.length === 3; + var root = mutatedByMap.get(mutated); + if (arguments.length === 2) { + mutator = key; + key = undefined; + } + if (!mutator.keyDependencies && !mutator.valueDependencies) { + var s = new Set(); + s.add(mutator); + mutator = { valueDependencies: s }; + } + var dependencyRecord = gotKey ? root.mutateDependenciesForKey.get(key) : root.mutateDependenciesForValue; + if (mutator.valueDependencies) { + canReflect.removeValues(dependencyRecord.valueDependencies, mutator.valueDependencies); + } + if (mutator.keyDependencies) { + canReflect.each(mutator.keyDependencies, function (keysSet, obj) { + var entry = dependencyRecord.keyDependencies.get(obj); + if (entry) { + canReflect.removeValues(entry, keysSet); + if (!entry.size) { + dependencyRecord.keyDependencies.delete(obj); + } + } + }); + } + }; + }; +}); +/*can-reflect-dependencies@1.1.1#src/is-function*/ +define('can-reflect-dependencies@1.1.1#src/is-function', function (require, exports, module) { + 'use strict'; + module.exports = function isFunction(value) { + return typeof value === 'function'; + }; +}); +/*can-reflect-dependencies@1.1.1#src/get-dependency-data-of*/ +define('can-reflect-dependencies@1.1.1#src/get-dependency-data-of', [ + 'require', + 'exports', + 'module', + 'can-symbol', + 'can-reflect', + './is-function', + 'can-assign' +], function (require, exports, module) { + 'use strict'; + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + var isFunction = require('./is-function'); + var canAssign = require('can-assign'); + var getWhatIChangeSymbol = canSymbol.for('can.getWhatIChange'); + var getKeyDependenciesSymbol = canSymbol.for('can.getKeyDependencies'); + var getValueDependenciesSymbol = canSymbol.for('can.getValueDependencies'); + var getKeyDependencies = function getKeyDependencies(obj, key) { + if (isFunction(obj[getKeyDependenciesSymbol])) { + return canReflect.getKeyDependencies(obj, key); + } + }; + var getValueDependencies = function getValueDependencies(obj) { + if (isFunction(obj[getValueDependenciesSymbol])) { + return canReflect.getValueDependencies(obj); + } + }; + var getMutatedKeyDependencies = function getMutatedKeyDependencies(mutatedByMap, obj, key) { + var root = mutatedByMap.get(obj); + var dependencyRecord; + if (root && root.mutateDependenciesForKey.has(key)) { + dependencyRecord = root.mutateDependenciesForKey.get(key); + } + return dependencyRecord; + }; + var getMutatedValueDependencies = function getMutatedValueDependencies(mutatedByMap, obj) { + var result; + var root = mutatedByMap.get(obj); + if (root) { + var dependencyRecord = root.mutateDependenciesForValue; + if (dependencyRecord.keyDependencies.size) { + result = result || {}; + result.keyDependencies = dependencyRecord.keyDependencies; + } + if (dependencyRecord.valueDependencies.size) { + result = result || {}; + result.valueDependencies = dependencyRecord.valueDependencies; + } + } + return result; + }; + var getWhatIChange = function getWhatIChange(obj, key) { + if (isFunction(obj[getWhatIChangeSymbol])) { + var gotKey = arguments.length === 2; + return gotKey ? canReflect.getWhatIChange(obj, key) : canReflect.getWhatIChange(obj); + } + }; + var isEmptyRecord = function isEmptyRecord(record) { + return record == null || !Object.keys(record).length || record.keyDependencies && !record.keyDependencies.size && (record.valueDependencies && !record.valueDependencies.size); + }; + var getWhatChangesMe = function getWhatChangesMe(mutatedByMap, obj, key) { + var gotKey = arguments.length === 3; + var mutate = gotKey ? getMutatedKeyDependencies(mutatedByMap, obj, key) : getMutatedValueDependencies(mutatedByMap, obj); + var derive = gotKey ? getKeyDependencies(obj, key) : getValueDependencies(obj); + if (!isEmptyRecord(mutate) || !isEmptyRecord(derive)) { + return canAssign(canAssign({}, mutate ? { mutate: mutate } : null), derive ? { derive: derive } : null); + } + }; + module.exports = function (mutatedByMap) { + return function getDependencyDataOf(obj, key) { + var gotKey = arguments.length === 2; + var whatChangesMe = gotKey ? getWhatChangesMe(mutatedByMap, obj, key) : getWhatChangesMe(mutatedByMap, obj); + var whatIChange = gotKey ? getWhatIChange(obj, key) : getWhatIChange(obj); + if (whatChangesMe || whatIChange) { + return canAssign(canAssign({}, whatIChange ? { whatIChange: whatIChange } : null), whatChangesMe ? { whatChangesMe: whatChangesMe } : null); + } + }; + }; +}); +/*can-reflect-dependencies@1.1.1#can-reflect-dependencies*/ +define('can-reflect-dependencies@1.1.1#can-reflect-dependencies', [ + 'require', + 'exports', + 'module', + './src/add-mutated-by', + './src/delete-mutated-by', + './src/get-dependency-data-of' +], function (require, exports, module) { + 'use strict'; + var addMutatedBy = require('./src/add-mutated-by'); + var deleteMutatedBy = require('./src/delete-mutated-by'); + var getDependencyDataOf = require('./src/get-dependency-data-of'); + var mutatedByMap = new WeakMap(); + module.exports = { + addMutatedBy: addMutatedBy(mutatedByMap), + deleteMutatedBy: deleteMutatedBy(mutatedByMap), + getDependencyDataOf: getDependencyDataOf(mutatedByMap) + }; +}); +/*can-stache-helpers@1.2.0#can-stache-helpers*/ +define('can-stache-helpers@1.2.0#can-stache-helpers', [ + 'require', + 'exports', + 'module', + 'can-namespace' +], function (require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + if (namespace.stacheHelpers) { + throw new Error('You can\'t have two versions of can-stache-helpers, check your dependencies'); + } else { + module.exports = namespace.stacheHelpers = {}; + } +}); +/*can-simple-observable@2.4.1#log*/ +define('can-simple-observable@2.4.1#log', [ + 'require', + 'exports', + 'module', + 'can-log/dev/dev', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var dev = require('can-log/dev/dev'); + var canReflect = require('can-reflect'); + function quoteString(x) { + return typeof x === 'string' ? JSON.stringify(x) : x; + } + module.exports = function log() { + }; +}); +/*can-simple-observable@2.4.1#can-simple-observable*/ +define('can-simple-observable@2.4.1#can-simple-observable', [ + 'require', + 'exports', + 'module', + './log', + 'can-namespace', + 'can-symbol', + 'can-reflect', + 'can-observation-recorder', + 'can-event-queue/value/value' +], function (require, exports, module) { + 'use strict'; + var log = require('./log'); + var ns = require('can-namespace'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + var ObservationRecorder = require('can-observation-recorder'); + var valueEventBindings = require('can-event-queue/value/value'); + var dispatchSymbol = canSymbol.for('can.dispatch'); + function SimpleObservable(initialValue) { + this._value = initialValue; + } + valueEventBindings(SimpleObservable.prototype); + canReflect.assignMap(SimpleObservable.prototype, { + log: log, + get: function () { + ObservationRecorder.add(this); + return this._value; + }, + set: function (value) { + var old = this._value; + this._value = value; + this[dispatchSymbol](value, old); + } + }); + Object.defineProperty(SimpleObservable.prototype, 'value', { + set: function (value) { + return this.set(value); + }, + get: function () { + return this.get(); + } + }); + var simpleObservableProto = { + 'can.getValue': SimpleObservable.prototype.get, + 'can.setValue': SimpleObservable.prototype.set, + 'can.isMapLike': false, + 'can.valueHasDependencies': function () { + return true; + } + }; + canReflect.assignSymbols(SimpleObservable.prototype, simpleObservableProto); + module.exports = ns.SimpleObservable = SimpleObservable; +}); +/*can-view-scope@4.11.1#scope-key-data*/ +define('can-view-scope@4.11.1#scope-key-data', [ + 'require', + 'exports', + 'module', + 'can-observation', + 'can-stache-key', + 'can-assign', + 'can-reflect', + 'can-symbol', + 'can-observation-recorder', + './make-compute-like', + 'can-reflect-dependencies', + 'can-event-queue/value/value', + 'can-stache-helpers', + 'can-simple-observable' +], function (require, exports, module) { + 'use strict'; + var Observation = require('can-observation'); + var observeReader = require('can-stache-key'); + var assign = require('can-assign'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var ObservationRecorder = require('can-observation-recorder'); + var makeComputeLike = require('./make-compute-like'); + var canReflectDeps = require('can-reflect-dependencies'); + var valueEventBindings = require('can-event-queue/value/value'); + var stacheHelpers = require('can-stache-helpers'); + var SimpleObservable = require('can-simple-observable'); + var dispatchSymbol = canSymbol.for('can.dispatch'); + var peekValue = ObservationRecorder.ignore(canReflect.getValue.bind(canReflect)); + var peekGet = ObservationRecorder.ignore(Observation.prototype.get); + var getFastPathRoot = ObservationRecorder.ignore(function (computeData) { + if (computeData.reads && computeData.reads.length === 1) { + var root = computeData.root; + if (root && root[canSymbol.for('can.getValue')]) { + root = canReflect.getValue(root); + } + return root && canReflect.isObservableLike(root) && canReflect.isMapLike(root) && typeof root[computeData.reads[0].key] !== 'function' && root; + } + return; + }); + var isEventObject = function (obj) { + return obj && typeof obj.batchNum === 'number' && typeof obj.type === 'string'; + }; + function callMutateWithRightArgs(method, mutated, reads, mutator) { + if (reads.length) { + method.call(canReflectDeps, mutated, reads[reads.length - 1].key, mutator); + } else { + method.call(canReflectDeps, mutated, mutator); + } + } + var ScopeKeyData = function (scope, key, options) { + this.startingScope = scope; + this.key = key; + this.read = this.read.bind(this); + this.dispatch = this.dispatch.bind(this); + if (key === 'debugger') { + this.startingScope = { _context: stacheHelpers }; + this.read = function () { + var helperOptions = { scope: scope }; + var debuggerHelper = stacheHelpers['debugger']; + return debuggerHelper(helperOptions); + }; + } + var observation = this.observation = new Observation(this.read, this); + this.options = assign({ observation: this.observation }, options); + this.fastPath = undefined; + this.root = undefined; + this.initialValue = undefined; + this.reads = undefined; + this.setRoot = undefined; + this._thisArg = new SimpleObservable(); + this.parentHasKey = undefined; + var valueDependencies = new Set(); + valueDependencies.add(observation); + this.dependencies = { valueDependencies: valueDependencies }; + this._latestValue = undefined; + }; + valueEventBindings(ScopeKeyData.prototype); + function fastOnBoundSet_Value() { + this._value = this.newVal; + } + function fastOnBoundSetValue() { + this.value = this.newVal; + } + assign(ScopeKeyData.prototype, { + constructor: ScopeKeyData, + dispatch: function dispatch(newVal) { + var old = this.value; + this._latestValue = this.value = newVal; + this[dispatchSymbol].call(this, this.value, old); + }, + onBound: function onBound() { + this.bound = true; + canReflect.onValue(this.observation, this.dispatch, 'notify'); + var fastPathRoot = getFastPathRoot(this); + if (fastPathRoot) { + this.toFastPath(fastPathRoot); + } + this._latestValue = this.value = peekGet.call(this.observation); + }, + onUnbound: function onUnbound() { + this.bound = false; + canReflect.offValue(this.observation, this.dispatch, 'notify'); + this.toSlowPath(); + }, + set: function (newVal) { + var root = this.root || this.setRoot; + if (root) { + if (this.reads.length) { + observeReader.write(root, this.reads, newVal, this.options); + } else { + canReflect.setValue(root, newVal); + } + } else { + this.startingScope.set(this.key, newVal, this.options); + } + }, + get: function () { + if (ObservationRecorder.isRecording()) { + ObservationRecorder.add(this); + if (!this.bound) { + Observation.temporarilyBind(this); + } + } + if (this.bound === true && this.fastPath === true) { + return this._latestValue; + } else { + return peekGet.call(this.observation); + } + }, + toFastPath: function (fastPathRoot) { + var self = this, observation = this.observation; + this.fastPath = true; + observation.dependencyChange = function (target, newVal) { + if (isEventObject(newVal)) { + throw 'no event objects!'; + } + if (target === fastPathRoot && typeof newVal !== 'function') { + self._latestValue = newVal; + this.newVal = newVal; + } else { + self.toSlowPath(); + } + return Observation.prototype.dependencyChange.apply(this, arguments); + }; + if (observation.hasOwnProperty('_value')) { + observation.onBound = fastOnBoundSet_Value; + } else { + observation.onBound = fastOnBoundSetValue; + } + }, + toSlowPath: function () { + this.observation.dependencyChange = Observation.prototype.dependencyChange; + this.observation.onBound = Observation.prototype.onBound; + this.fastPath = false; + }, + read: function () { + var data; + if (this.root) { + data = observeReader.read(this.root, this.reads, this.options); + this.thisArg = data.parent; + return data.value; + } + data = this.startingScope.read(this.key, this.options); + this.scope = data.scope; + this.reads = data.reads; + this.root = data.rootObserve; + this.setRoot = data.setRoot; + this.thisArg = data.thisArg; + this.parentHasKey = data.parentHasKey; + return this.initialValue = data.value; + }, + hasDependencies: function () { + return canReflect.valueHasDependencies(this.observation); + } + }); + Object.defineProperty(ScopeKeyData.prototype, 'thisArg', { + get: function () { + return this._thisArg.get(); + }, + set: function (newVal) { + this._thisArg.set(newVal); + } + }); + var scopeKeyDataPrototype = { + 'can.getValue': ScopeKeyData.prototype.get, + 'can.setValue': ScopeKeyData.prototype.set, + 'can.valueHasDependencies': ScopeKeyData.prototype.hasDependencies, + 'can.getValueDependencies': function () { + return this.dependencies; + }, + 'can.getPriority': function () { + return canReflect.getPriority(this.observation); + }, + 'can.setPriority': function (newPriority) { + canReflect.setPriority(this.observation, newPriority); + } + }; + canReflect.assignSymbols(ScopeKeyData.prototype, scopeKeyDataPrototype); + Object.defineProperty(ScopeKeyData.prototype, 'compute', { + get: function () { + var compute = makeComputeLike(this); + Object.defineProperty(this, 'compute', { + value: compute, + writable: false, + configurable: false + }); + return compute; + }, + configurable: true + }); + module.exports = ScopeKeyData; +}); +/*can-view-scope@4.11.1#compute_data*/ +define('can-view-scope@4.11.1#compute_data', [ + 'require', + 'exports', + 'module', + './scope-key-data' +], function (require, exports, module) { + 'use strict'; + var ScopeKeyData = require('./scope-key-data'); + module.exports = function (scope, key, options) { + return new ScopeKeyData(scope, key, options || { args: [] }); + }; +}); +/*can-view-scope@4.11.1#can-view-scope*/ +define('can-view-scope@4.11.1#can-view-scope', [ + 'require', + 'exports', + 'module', + 'can-stache-key', + 'can-observation-recorder', + './template-context', + './compute_data', + 'can-assign', + 'can-namespace', + 'can-reflect', + 'can-log/dev/dev', + 'can-define-lazy-value', + 'can-stache-helpers', + 'can-simple-map' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var stacheKey = require('can-stache-key'); + var ObservationRecorder = require('can-observation-recorder'); + var TemplateContext = require('./template-context'); + var makeComputeData = require('./compute_data'); + var assign = require('can-assign'); + var namespace = require('can-namespace'); + var canReflect = require('can-reflect'); + var canLog = require('can-log/dev/dev'); + var defineLazyValue = require('can-define-lazy-value'); + var stacheHelpers = require('can-stache-helpers'); + var SimpleMap = require('can-simple-map'); + function canHaveProperties(obj) { + return obj != null; + } + function returnFalse() { + return false; + } + var LetContext = SimpleMap.extend('LetContext', {}); + function Scope(context, parent, meta) { + this._context = context; + this._parent = parent; + this._meta = meta || {}; + this.__cache = {}; + } + var parentContextSearch = /(\.\.\/)|(\.\/)|(this[\.@])/g; + assign(Scope, { + read: stacheKey.read, + TemplateContext: TemplateContext, + keyInfo: function (attr) { + if (attr === './') { + attr = 'this'; + } + var info = { remainingKey: attr }; + info.isScope = attr === 'scope'; + if (info.isScope) { + return info; + } + var firstSix = attr.substr(0, 6); + info.isInScope = firstSix === 'scope.' || firstSix === 'scope@'; + if (info.isInScope) { + info.remainingKey = attr.substr(6); + return info; + } else if (firstSix === 'scope/') { + info.walkScope = true; + info.remainingKey = attr.substr(6); + return info; + } else if (attr.substr(0, 7) === '@scope/') { + info.walkScope = true; + info.remainingKey = attr.substr(7); + return info; + } + info.parentContextWalkCount = 0; + info.remainingKey = attr.replace(parentContextSearch, function (token, parentContext, dotSlash, thisContext, index) { + info.isContextBased = true; + if (parentContext !== undefined) { + info.parentContextWalkCount++; + } + return ''; + }); + if (info.remainingKey === '..') { + info.parentContextWalkCount++; + info.remainingKey = 'this'; + } else if (info.remainingKey === '.' || info.remainingKey === '') { + info.remainingKey = 'this'; + } + if (info.remainingKey === 'this') { + info.isContextBased = true; + } + return info; + }, + isTemplateContextOrCanNotHaveProperties: function (currentScope) { + var currentContext = currentScope._context; + if (currentContext instanceof TemplateContext) { + return true; + } else if (!canHaveProperties(currentContext)) { + return true; + } + return false; + }, + shouldSkipIfSpecial: function (currentScope) { + var isSpecialContext = currentScope._meta.special === true; + if (isSpecialContext === true) { + return true; + } + if (Scope.isTemplateContextOrCanNotHaveProperties(currentScope)) { + return true; + } + return false; + }, + shouldSkipEverythingButSpecial: function (currentScope) { + var isSpecialContext = currentScope._meta.special === true; + if (isSpecialContext === false) { + return true; + } + if (Scope.isTemplateContextOrCanNotHaveProperties(currentScope)) { + return true; + } + return false; + }, + makeShouldExitOnSecondNormalContext: function () { + var foundNormalContext = false; + return function shouldExitOnSecondNormalContext(currentScope) { + var isNormalContext = !currentScope.isSpecial(); + var shouldExit = isNormalContext && foundNormalContext; + if (isNormalContext) { + foundNormalContext = true; + } + return shouldExit; + }; + }, + makeShouldExitAfterFirstNormalContext: function () { + var foundNormalContext = false; + return function shouldExitAfterFirstNormalContext(currentScope) { + if (foundNormalContext) { + return true; + } + var isNormalContext = !currentScope.isSpecial(); + if (isNormalContext) { + foundNormalContext = true; + } + return false; + }; + }, + makeShouldSkipSpecialContexts: function (parentContextWalkCount) { + var walkCount = parentContextWalkCount || 0; + return function shouldSkipSpecialContexts(currentScope) { + if (walkCount < 0 && currentScope._meta.notContext) { + return false; + } + if (currentScope.isSpecial()) { + return true; + } + walkCount--; + if (walkCount < 0) { + return false; + } + return true; + }; + } + }); + assign(Scope.prototype, { + add: function (context, meta) { + if (context !== this._context) { + return new this.constructor(context, this, meta); + } else { + return this; + } + }, + find: function (attr, options) { + var keyReads = stacheKey.reads(attr); + var howToRead = { + shouldExit: returnFalse, + shouldSkip: Scope.shouldSkipIfSpecial, + shouldLookForHelper: true, + read: stacheKey.read + }; + var result = this._walk(keyReads, options, howToRead); + return result.value; + }, + readFromSpecialContext: function (key) { + return this._walk([{ + key: key, + at: false + }], { special: true }, { + shouldExit: returnFalse, + shouldSkip: Scope.shouldSkipEverythingButSpecial, + shouldLookForHelper: false, + read: stacheKey.read + }); + }, + readFromTemplateContext: function (key, readOptions) { + var keyReads = stacheKey.reads(key); + return stacheKey.read(this.templateContext, keyReads, readOptions); + }, + read: function (attr, options) { + options = options || {}; + return this.readKeyInfo(Scope.keyInfo(attr), options || {}); + }, + readKeyInfo: function (keyInfo, options) { + var readValue, keyReads, howToRead = { read: options.read || stacheKey.read }; + if (keyInfo.isScope) { + return { value: this }; + } else if (keyInfo.isInScope) { + keyReads = stacheKey.reads(keyInfo.remainingKey); + readValue = stacheKey.read(this, keyReads, options); + if (typeof readValue.value === 'undefined' && !readValue.parentHasKey) { + readValue = this.readFromTemplateContext(keyInfo.remainingKey, options); + } + return assign(readValue, { thisArg: keyReads.length > 0 ? readValue.parent : undefined }); + } else if (keyInfo.isContextBased) { + if (keyInfo.remainingKey !== 'this') { + keyReads = stacheKey.reads(keyInfo.remainingKey); + } else { + keyReads = []; + } + howToRead.shouldExit = Scope.makeShouldExitOnSecondNormalContext(); + howToRead.shouldSkip = Scope.makeShouldSkipSpecialContexts(keyInfo.parentContextWalkCount); + howToRead.shouldLookForHelper = true; + return this._walk(keyReads, options, howToRead); + } else if (keyInfo.walkScope) { + howToRead.shouldExit = returnFalse; + howToRead.shouldSkip = Scope.shouldSkipIfSpecial; + howToRead.shouldLookForHelper = true; + keyReads = stacheKey.reads(keyInfo.remainingKey); + return this._walk(keyReads, options, howToRead); + } else { + keyReads = stacheKey.reads(keyInfo.remainingKey); + var isSpecialRead = options && options.special === true; + howToRead.shouldExit = Scope.makeShouldExitOnSecondNormalContext(); + howToRead.shouldSkip = isSpecialRead ? Scope.shouldSkipEverythingButSpecial : Scope.shouldSkipIfSpecial; + howToRead.shouldLookForHelper = isSpecialRead ? false : true; + return this._walk(keyReads, options, howToRead); + } + }, + _walk: function (keyReads, options, howToRead) { + var currentScope = this, currentContext, undefinedObserves = [], currentObserve, currentReads, setObserveDepth = -1, currentSetReads, currentSetObserve, readOptions = assign({ + foundObservable: function (observe, nameIndex) { + currentObserve = observe; + currentReads = keyReads.slice(nameIndex); + }, + earlyExit: function (parentValue, nameIndex) { + var isVariableScope = currentScope._meta.variable === true, updateSetObservable = false; + if (isVariableScope === true && nameIndex === 0) { + updateSetObservable = canReflect.hasKey(parentValue, keyReads[nameIndex].key); + } else { + updateSetObservable = nameIndex > setObserveDepth || nameIndex === setObserveDepth && (typeof parentValue === 'object' && canReflect.hasOwnKey(parentValue, keyReads[nameIndex].key)); + } + if (updateSetObservable) { + currentSetObserve = currentObserve; + currentSetReads = currentReads; + setObserveDepth = nameIndex; + } + } + }, options); + var isRecording = ObservationRecorder.isRecording(), readAContext = false; + while (currentScope) { + if (howToRead.shouldSkip(currentScope) === true) { + currentScope = currentScope._parent; + continue; + } + if (howToRead.shouldExit(currentScope) === true) { + break; + } + readAContext = true; + currentContext = currentScope._context; + var getObserves = ObservationRecorder.trap(); + var data = howToRead.read(currentContext, keyReads, readOptions); + var observes = getObserves(); + if (data.value !== undefined || data.parentHasKey) { + if (!observes.length && isRecording) { + currentObserve = data.parent; + currentReads = keyReads.slice(keyReads.length - 1); + } else { + ObservationRecorder.addMany(observes); + } + return { + scope: currentScope, + rootObserve: currentObserve, + value: data.value, + reads: currentReads, + thisArg: data.parent, + parentHasKey: data.parentHasKey + }; + } else { + undefinedObserves.push.apply(undefinedObserves, observes); + } + currentScope = currentScope._parent; + } + if (howToRead.shouldLookForHelper) { + var helper = this.getHelperOrPartial(keyReads); + if (helper && helper.value) { + return { value: helper.value }; + } + } + ObservationRecorder.addMany(undefinedObserves); + return { + setRoot: currentSetObserve, + reads: currentSetReads, + value: undefined, + noContextAvailable: !readAContext + }; + }, + getDataForScopeSet: function getDataForScopeSet(key, options) { + var keyInfo = Scope.keyInfo(key); + var firstSearchedContext; + var opts = assign({ + read: function (context, keys) { + if (firstSearchedContext === undefined && !(context instanceof LetContext)) { + firstSearchedContext = context; + } + if (keys.length > 1) { + var parentKeys = keys.slice(0, keys.length - 1); + var parent = stacheKey.read(context, parentKeys, options).value; + if (parent != null && canReflect.hasKey(parent, keys[keys.length - 1].key)) { + return { + parent: parent, + parentHasKey: true, + value: undefined + }; + } else { + return {}; + } + } else if (keys.length === 1) { + if (canReflect.hasKey(context, keys[0].key)) { + return { + parent: context, + parentHasKey: true, + value: undefined + }; + } else { + return {}; + } + } else { + return { value: context }; + } + } + }, options); + var readData = this.readKeyInfo(keyInfo, opts); + if (keyInfo.remainingKey === 'this') { + return { + parent: readData.value, + how: 'setValue' + }; + } + var parent; + var props = keyInfo.remainingKey.split('.'); + var propName = props.pop(); + if (readData.thisArg) { + parent = readData.thisArg; + } else if (firstSearchedContext) { + parent = firstSearchedContext; + } + if (parent === undefined) { + return { error: 'Attempting to set a value at ' + key + ' where the context is undefined.' }; + } + if (!canReflect.isObservableLike(parent) && canReflect.isObservableLike(parent[propName])) { + if (canReflect.isMapLike(parent[propName])) { + return { + parent: parent, + key: propName, + how: 'updateDeep', + warn: 'can-view-scope: Merging data into "' + propName + '" because its parent is non-observable' + }; + } else if (canReflect.isValueLike(parent[propName])) { + return { + parent: parent, + key: propName, + how: 'setValue' + }; + } else { + return { + parent: parent, + how: 'write', + key: propName, + passOptions: true + }; + } + } else { + return { + parent: parent, + how: 'write', + key: propName, + passOptions: true + }; + } + }, + getHelper: function (keyReads) { + console.warn('.getHelper is deprecated, use .getHelperOrPartial'); + return this.getHelperOrPartial(keyReads); + }, + getHelperOrPartial: function (keyReads) { + var scope = this, context, helper; + while (scope) { + context = scope._context; + if (context instanceof TemplateContext) { + helper = stacheKey.read(context.helpers, keyReads, { proxyMethods: false }); + if (helper.value !== undefined) { + return helper; + } + helper = stacheKey.read(context.partials, keyReads, { proxyMethods: false }); + if (helper.value !== undefined) { + return helper; + } + } + scope = scope._parent; + } + return stacheKey.read(stacheHelpers, keyReads, { proxyMethods: false }); + }, + get: function (key, options) { + options = assign({ isArgument: true }, options); + var res = this.read(key, options); + return res.value; + }, + peek: ObservationRecorder.ignore(function (key, options) { + return this.get(key, options); + }), + peak: ObservationRecorder.ignore(function (key, options) { + return this.peek(key, options); + }), + getScope: function (tester) { + var scope = this; + while (scope) { + if (tester(scope)) { + return scope; + } + scope = scope._parent; + } + }, + getContext: function (tester) { + var res = this.getScope(tester); + return res && res._context; + }, + getTemplateContext: function () { + var lastScope; + var templateContext = this.getScope(function (scope) { + lastScope = scope; + return scope._context instanceof TemplateContext; + }); + if (!templateContext) { + templateContext = new Scope(new TemplateContext()); + lastScope._parent = templateContext; + } + return templateContext; + }, + addTemplateContext: function () { + return this.add(new TemplateContext()); + }, + addLetContext: function (values) { + return this.add(new LetContext(values || {}), { variable: true }); + }, + getRoot: function () { + var cur = this, child = this; + while (cur._parent) { + child = cur; + cur = cur._parent; + } + if (cur._context instanceof TemplateContext) { + cur = child; + } + return cur._context; + }, + getViewModel: function () { + var vmScope = this.getScope(function (scope) { + return scope._meta.viewModel; + }); + return vmScope && vmScope._context; + }, + getTop: function () { + var top; + this.getScope(function (scope) { + if (scope._meta.viewModel) { + top = scope; + } + return false; + }); + return top && top._context; + }, + getPathsForKey: function getPathsForKey(key) { + }, + hasKey: function hasKey(key) { + var reads = stacheKey.reads(key); + var readValue; + if (reads[0].key === 'scope') { + readValue = stacheKey.read(this, reads.slice(1), key); + } else { + readValue = stacheKey.read(this._context, reads, key); + } + return readValue.foundLastParent && readValue.parentHasKey; + }, + set: function (key, value, options) { + options = options || {}; + var data = this.getDataForScopeSet(key, options); + var parent = data.parent; + if (data.warn) { + canLog.warn(data.warn); + } + switch (data.how) { + case 'set': + parent.set(data.key, value, data.passOptions ? options : undefined); + break; + case 'write': + stacheKey.write(parent, data.key, value, options); + break; + case 'setValue': + canReflect.setValue('key' in data ? parent[data.key] : parent, value); + break; + case 'setKeyValue': + canReflect.setKeyValue(parent, data.key, value); + break; + case 'updateDeep': + canReflect.updateDeep(parent[data.key], value); + break; + } + }, + attr: ObservationRecorder.ignore(function (key, value, options) { + canLog.warn('can-view-scope::attr is deprecated, please use peek, get or set'); + options = assign({ isArgument: true }, options); + if (arguments.length === 2) { + return this.set(key, value, options); + } else { + return this.get(key, options); + } + }), + computeData: function (key, options) { + return makeComputeData(this, key, options); + }, + compute: function (key, options) { + return this.computeData(key, options).compute; + }, + cloneFromRef: function () { + var scopes = []; + var scope = this, context, parent; + while (scope) { + context = scope._context; + if (context instanceof TemplateContext) { + parent = scope._parent; + break; + } + scopes.unshift(scope); + scope = scope._parent; + } + if (parent) { + scopes.forEach(function (scope) { + parent = parent.add(scope._context, scope._meta); + }); + return parent; + } else { + return this; + } + }, + isSpecial: function () { + return this._meta.notContext || this._meta.special || this._context instanceof TemplateContext || this._meta.variable; + } + }); + Scope.prototype._read = Scope.prototype._walk; + canReflect.assignSymbols(Scope.prototype, { 'can.hasKey': Scope.prototype.hasKey }); + var templateContextPrimitives = [ + 'filename', + 'lineNumber' + ]; + templateContextPrimitives.forEach(function (key) { + Object.defineProperty(Scope.prototype, key, { + get: function () { + return this.readFromTemplateContext(key).value; + }, + set: function (val) { + this.templateContext[key] = val; + } + }); + }); + defineLazyValue(Scope.prototype, 'templateContext', function () { + return this.getTemplateContext()._context; + }); + defineLazyValue(Scope.prototype, 'root', function () { + canLog.warn('`scope.root` is deprecated. Use either `scope.top` or `scope.vm` instead.'); + return this.getRoot(); + }); + defineLazyValue(Scope.prototype, 'vm', function () { + return this.getViewModel(); + }); + defineLazyValue(Scope.prototype, 'top', function () { + return this.getTop(); + }); + defineLazyValue(Scope.prototype, 'helpers', function () { + return stacheHelpers; + }); + var specialKeywords = [ + 'index', + 'key', + 'element', + 'event', + 'viewModel', + 'arguments', + 'helperOptions' + ]; + specialKeywords.forEach(function (key) { + Object.defineProperty(Scope.prototype, key, { + get: function () { + return this.readFromSpecialContext(key).value; + } + }); + }); + namespace.view = namespace.view || {}; + module.exports = namespace.view.Scope = Scope; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-simple-observable@2.4.1#settable/settable*/ +define('can-simple-observable@2.4.1#settable/settable', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-observation-recorder', + '../can-simple-observable', + 'can-observation', + 'can-queues', + '../log', + 'can-event-queue/value/value' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var ObservationRecorder = require('can-observation-recorder'); + var SimpleObservable = require('../can-simple-observable'); + var Observation = require('can-observation'); + var queues = require('can-queues'); + var log = require('../log'); + var valueEventBindings = require('can-event-queue/value/value'); + var peek = ObservationRecorder.ignore(canReflect.getValue.bind(canReflect)); + function SettableObservable(fn, context, initialValue) { + this.lastSetValue = new SimpleObservable(initialValue); + function observe() { + return fn.call(context, this.lastSetValue.get()); + } + this.handler = this.handler.bind(this); + this.observation = new Observation(observe, this); + } + valueEventBindings(SettableObservable.prototype); + canReflect.assignMap(SettableObservable.prototype, { + log: log, + constructor: SettableObservable, + handler: function (newVal) { + var old = this._value, reasonLog; + this._value = newVal; + queues.enqueueByQueue(this.handlers.getNode([]), this, [ + newVal, + old + ], null, reasonLog); + }, + onBound: function () { + if (!this.bound) { + this.bound = true; + this.activate(); + } + }, + activate: function () { + canReflect.onValue(this.observation, this.handler, 'notify'); + this._value = peek(this.observation); + }, + onUnbound: function () { + this.bound = false; + canReflect.offValue(this.observation, this.handler, 'notify'); + }, + set: function (newVal) { + var oldVal = this.lastSetValue.get(); + if (canReflect.isObservableLike(oldVal) && canReflect.isValueLike(oldVal) && !canReflect.isObservableLike(newVal)) { + canReflect.setValue(oldVal, newVal); + } else { + if (newVal !== oldVal) { + this.lastSetValue.set(newVal); + } + } + }, + get: function () { + if (ObservationRecorder.isRecording()) { + ObservationRecorder.add(this); + if (!this.bound) { + this.onBound(); + } + } + if (this.bound === true) { + return this._value; + } else { + return this.observation.get(); + } + }, + hasDependencies: function () { + return canReflect.valueHasDependencies(this.observation); + }, + getValueDependencies: function () { + return canReflect.getValueDependencies(this.observation); + } + }); + Object.defineProperty(SettableObservable.prototype, 'value', { + set: function (value) { + return this.set(value); + }, + get: function () { + return this.get(); + } + }); + canReflect.assignSymbols(SettableObservable.prototype, { + 'can.getValue': SettableObservable.prototype.get, + 'can.setValue': SettableObservable.prototype.set, + 'can.isMapLike': false, + 'can.getPriority': function () { + return canReflect.getPriority(this.observation); + }, + 'can.setPriority': function (newPriority) { + canReflect.setPriority(this.observation, newPriority); + }, + 'can.valueHasDependencies': SettableObservable.prototype.hasDependencies, + 'can.getValueDependencies': SettableObservable.prototype.getValueDependencies + }); + module.exports = SettableObservable; +}); +/*can-stache@4.15.9#src/key-observable*/ +define('can-stache@4.15.9#src/key-observable', [ + 'require', + 'exports', + 'module', + 'can-simple-observable/settable/settable', + 'can-stache-key' +], function (require, exports, module) { + 'use strict'; + var SettableObservable = require('can-simple-observable/settable/settable'); + var stacheKey = require('can-stache-key'); + function KeyObservable(root, key) { + key = '' + key; + this.key = key; + this.root = root; + SettableObservable.call(this, function () { + return stacheKey.get(this, key); + }, root); + } + KeyObservable.prototype = Object.create(SettableObservable.prototype); + KeyObservable.prototype.set = function (newVal) { + stacheKey.set(this.root, this.key, newVal); + }; + module.exports = KeyObservable; +}); +/*can-stache@4.15.9#src/utils*/ +define('can-stache@4.15.9#src/utils', [ + 'require', + 'exports', + 'module', + 'can-view-scope', + 'can-observation-recorder', + 'can-stache-key', + 'can-reflect', + './key-observable', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var Scope = require('can-view-scope'); + var ObservationRecorder = require('can-observation-recorder'); + var observationReader = require('can-stache-key'); + var canReflect = require('can-reflect'); + var KeyObservable = require('./key-observable'); + var canSymbol = require('can-symbol'); + var isViewSymbol = canSymbol.for('can.isView'); + var createNoOpRenderer = function (metadata) { + return function noop() { + if (metadata) { + metadata.rendered = true; + } + }; + }; + module.exports = { + last: function (arr) { + return arr != null && arr[arr.length - 1]; + }, + emptyHandler: function () { + }, + jsonParse: function (str) { + if (str[0] === '\'') { + return str.substr(1, str.length - 2); + } else if (str === 'undefined') { + return undefined; + } else { + return JSON.parse(str); + } + }, + mixins: { + last: function () { + return this.stack[this.stack.length - 1]; + }, + add: function (chars) { + this.last().add(chars); + }, + subSectionDepth: function () { + return this.stack.length - 1; + } + }, + createRenderers: function (helperOptions, scope, nodeList, truthyRenderer, falseyRenderer, isStringOnly) { + helperOptions.fn = truthyRenderer ? this.makeRendererConvertScopes(truthyRenderer, scope, nodeList, isStringOnly, helperOptions.metadata) : createNoOpRenderer(helperOptions.metadata); + helperOptions.inverse = falseyRenderer ? this.makeRendererConvertScopes(falseyRenderer, scope, nodeList, isStringOnly, helperOptions.metadata) : createNoOpRenderer(helperOptions.metadata); + helperOptions.isSection = !!(truthyRenderer || falseyRenderer); + }, + makeRendererConvertScopes: function (renderer, parentScope, nodeList, observeObservables, metadata) { + var convertedRenderer = function (newScope, newOptions, parentNodeList) { + if (newScope !== undefined && !(newScope instanceof Scope)) { + if (parentScope) { + newScope = parentScope.add(newScope); + } else { + newScope = new Scope(newScope || {}); + } + } + if (metadata) { + metadata.rendered = true; + } + var result = renderer(newScope || parentScope, parentNodeList || nodeList); + return result; + }; + return observeObservables ? convertedRenderer : ObservationRecorder.ignore(convertedRenderer); + }, + makeView: function (renderer) { + var view = ObservationRecorder.ignore(function (scope, nodeList) { + if (!(scope instanceof Scope)) { + scope = new Scope(scope); + } + return renderer(scope, nodeList); + }); + view[isViewSymbol] = true; + return view; + }, + getItemsStringContent: function (items, isObserveList, helperOptions) { + var txt = '', len = observationReader.get(items, 'length'), isObservable = canReflect.isObservableLike(items); + for (var i = 0; i < len; i++) { + var item = isObservable ? new KeyObservable(items, i) : items[i]; + txt += helperOptions.fn(item); + } + return txt; + }, + getItemsFragContent: function (items, helperOptions, scope) { + var result = [], len = observationReader.get(items, 'length'), isObservable = canReflect.isObservableLike(items), hashExprs = helperOptions.exprData && helperOptions.exprData.hashExprs, hashOptions; + if (canReflect.size(hashExprs) > 0) { + hashOptions = {}; + canReflect.eachKey(hashExprs, function (exprs, key) { + hashOptions[exprs.key] = key; + }); + } + for (var i = 0; i < len; i++) { + var aliases = {}; + var item = isObservable ? new KeyObservable(items, i) : items[i]; + if (canReflect.size(hashOptions) > 0) { + if (hashOptions.value) { + aliases[hashOptions.value] = item; + } + if (hashOptions.index) { + aliases[hashOptions.index] = i; + } + } + result.push(helperOptions.fn(scope.add(aliases, { notContext: true }).add({ index: i }, { special: true }).add(item))); + } + return result; + } + }; +}); +/*can-stache@4.15.9#src/html_section*/ +define('can-stache@4.15.9#src/html_section', [ + 'require', + 'exports', + 'module', + 'can-view-target', + './utils', + 'can-globals/document/document', + 'can-assign' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var target = require('can-view-target'); + var utils = require('./utils'); + var getDocument = require('can-globals/document/document'); + var assign = require('can-assign'); + var last = utils.last; + var decodeHTML = typeof document !== 'undefined' && function () { + var el = getDocument().createElement('div'); + return function (html) { + if (html.indexOf('&') === -1) { + return html.replace(/\r\n/g, '\n'); + } + el.innerHTML = html; + return el.childNodes.length === 0 ? '' : el.childNodes.item(0).nodeValue; + }; + }(); + var HTMLSectionBuilder = function (filename) { + if (filename) { + this.filename = filename; + } + this.stack = [new HTMLSection()]; + }; + assign(HTMLSectionBuilder.prototype, utils.mixins); + assign(HTMLSectionBuilder.prototype, { + startSubSection: function (process) { + var newSection = new HTMLSection(process); + this.stack.push(newSection); + return newSection; + }, + endSubSectionAndReturnRenderer: function () { + if (this.last().isEmpty()) { + this.stack.pop(); + return null; + } else { + var htmlSection = this.endSection(); + return utils.makeView(htmlSection.compiled.hydrate.bind(htmlSection.compiled)); + } + }, + startSection: function (process) { + var newSection = new HTMLSection(process); + this.last().add(newSection.targetCallback); + this.stack.push(newSection); + }, + endSection: function () { + this.last().compile(); + return this.stack.pop(); + }, + inverse: function () { + this.last().inverse(); + }, + compile: function () { + var compiled = this.stack.pop().compile(); + return utils.makeView(compiled.hydrate.bind(compiled)); + }, + push: function (chars) { + this.last().push(chars); + }, + pop: function () { + return this.last().pop(); + }, + removeCurrentNode: function () { + this.last().removeCurrentNode(); + } + }); + var HTMLSection = function (process) { + this.data = 'targetData'; + this.targetData = []; + this.targetStack = []; + var self = this; + this.targetCallback = function (scope, sectionNode) { + process.call(this, scope, sectionNode, self.compiled.hydrate.bind(self.compiled), self.inverseCompiled && self.inverseCompiled.hydrate.bind(self.inverseCompiled)); + }; + }; + assign(HTMLSection.prototype, { + inverse: function () { + this.inverseData = []; + this.data = 'inverseData'; + }, + push: function (data) { + this.add(data); + this.targetStack.push(data); + }, + pop: function () { + return this.targetStack.pop(); + }, + add: function (data) { + if (typeof data === 'string') { + data = decodeHTML(data); + } + if (this.targetStack.length) { + last(this.targetStack).children.push(data); + } else { + this[this.data].push(data); + } + }, + compile: function () { + this.compiled = target(this.targetData, getDocument()); + if (this.inverseData) { + this.inverseCompiled = target(this.inverseData, getDocument()); + delete this.inverseData; + } + this.targetStack = this.targetData = null; + return this.compiled; + }, + removeCurrentNode: function () { + var children = this.children(); + return children.pop(); + }, + children: function () { + if (this.targetStack.length) { + return last(this.targetStack).children; + } else { + return this[this.data]; + } + }, + isEmpty: function () { + return !this.targetData.length; + } + }); + HTMLSectionBuilder.HTMLSection = HTMLSection; + module.exports = HTMLSectionBuilder; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-view-live@4.2.7#lib/core*/ +define('can-view-live@4.2.7#lib/core', [ + 'require', + 'exports', + 'module', + 'can-view-parser', + 'can-dom-mutate', + 'can-view-nodelist', + 'can-fragment', + 'can-child-nodes', + 'can-reflect', + 'can-reflect-dependencies' +], function (require, exports, module) { + 'use strict'; + var parser = require('can-view-parser'); + var domMutate = require('can-dom-mutate'); + var nodeLists = require('can-view-nodelist'); + var makeFrag = require('can-fragment'); + var childNodes = require('can-child-nodes'); + var canReflect = require('can-reflect'); + var canReflectDeps = require('can-reflect-dependencies'); + function contains(parent, child) { + if (parent.contains) { + return parent.contains(child); + } + if (parent.nodeType === Node.DOCUMENT_NODE && parent.documentElement) { + return contains(parent.documentElement, child); + } else { + child = child.parentNode; + if (child === parent) { + return true; + } + return false; + } + } + var live = { + setup: function (el, bind, unbind) { + var tornDown = false, removalDisposal, data, teardown = function () { + if (!tornDown) { + tornDown = true; + unbind(data); + if (removalDisposal) { + removalDisposal(); + removalDisposal = undefined; + } + } + return true; + }; + data = { + teardownCheck: function (parent) { + return parent ? false : teardown(); + } + }; + removalDisposal = domMutate.onNodeRemoval(el, function () { + var doc = el.ownerDocument; + if (!contains(doc, el)) { + teardown(); + } + }); + bind(data); + return data; + }, + listen: function (el, compute, change, queueName) { + return live.setup(el, function bind() { + canReflect.onValue(compute, change, queueName || 'notify'); + }, function unbind(data) { + canReflect.offValue(compute, change, queueName || 'notify'); + if (data.nodeList) { + nodeLists.unregister(data.nodeList); + } + }); + }, + getAttributeParts: function (newVal) { + var attrs = {}, attr; + parser.parseAttrs(newVal, { + attrStart: function (name) { + attrs[name] = ''; + attr = name; + }, + attrValue: function (value) { + attrs[attr] += value; + }, + attrEnd: function () { + } + }); + return attrs; + }, + isNode: function (obj) { + return obj && obj.nodeType; + }, + addTextNodeIfNoChildren: function (frag) { + if (!frag.firstChild) { + frag.appendChild(frag.ownerDocument.createTextNode('')); + } + }, + replace: function (nodes, val, teardown) { + var oldNodes = nodes.slice(0), frag = makeFrag(val); + nodeLists.register(nodes, teardown); + nodeLists.update(nodes, childNodes(frag)); + nodeLists.replace(oldNodes, frag); + return nodes; + }, + getParentNode: function (el, defaultParentNode) { + return defaultParentNode && el.parentNode.nodeType === 11 ? defaultParentNode : el.parentNode; + }, + makeString: function (txt) { + return txt == null ? '' : '' + txt; + } + }; + module.exports = live; +}); +/*can-dom-data-state@1.0.5#can-dom-data-state*/ +define('can-dom-data-state@1.0.5#can-dom-data-state', [ + 'require', + 'exports', + 'module', + 'can-namespace', + 'can-dom-mutate', + 'can-cid' +], function (require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + var domMutate = require('can-dom-mutate'); + var CID = require('can-cid'); + var isEmptyObject = function (obj) { + for (var prop in obj) { + return false; + } + return true; + }; + var data = {}; + var removedDisposalMap = {}; + var deleteNode = function () { + var id = CID.get(this); + var nodeDeleted = false; + if (id && data[id]) { + nodeDeleted = true; + delete data[id]; + } + if (removedDisposalMap[id]) { + removedDisposalMap[id](); + delete removedDisposalMap[id]; + } + return nodeDeleted; + }; + var setData = function (name, value) { + var id = CID(this); + var store = data[id] || (data[id] = {}); + if (name !== undefined) { + store[name] = value; + var isNode = !!(this && typeof this.nodeType === 'number'); + if (isNode && !removedDisposalMap[id]) { + var target = this; + removedDisposalMap[id] = domMutate.onNodeRemoval(target, function () { + var doc = target.ownerDocument; + var ownerNode = doc.contains ? doc : doc.documentElement; + if (!ownerNode || !ownerNode.contains(target)) { + setTimeout(function () { + deleteNode.call(target); + }, 13); + } + }); + } + } + return store; + }; + var domDataState = { + _data: data, + _removalDisposalMap: removedDisposalMap, + getCid: function () { + return CID.get(this); + }, + cid: function () { + return CID(this); + }, + expando: CID.domExpando, + get: function (key) { + var id = CID.get(this), store = id && data[id]; + return key === undefined ? store : store && store[key]; + }, + set: setData, + clean: function (prop) { + var id = CID.get(this); + var itemData = data[id]; + if (itemData && itemData[prop]) { + delete itemData[prop]; + } + if (isEmptyObject(itemData)) { + deleteNode.call(this); + } + }, + delete: deleteNode + }; + if (namespace.domDataState) { + throw new Error('You can\'t have two versions of can-dom-data-state, check your dependencies'); + } else { + module.exports = namespace.domDataState = domDataState; + } +}); +/*can-diff@1.4.2#list/list*/ +define('can-diff@1.4.2#list/list', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var slice = [].slice; + function defaultIdentity(a, b) { + return a === b; + } + function makeIdentityFromMapSchema(typeSchema) { + if (typeSchema.identity && typeSchema.identity.length) { + return function identityCheck(a, b) { + var aId = canReflect.getIdentity(a, typeSchema), bId = canReflect.getIdentity(b, typeSchema); + return aId === bId; + }; + } else { + return defaultIdentity; + } + } + function makeIdentityFromListSchema(listSchema) { + return listSchema.values != null ? makeIdentityFromMapSchema(canReflect.getSchema(listSchema.values)) : defaultIdentity; + } + function makeIdentity(oldList, oldListLength) { + var listSchema = canReflect.getSchema(oldList), typeSchema; + if (listSchema != null) { + if (listSchema.values != null) { + typeSchema = canReflect.getSchema(listSchema.values); + } else { + return defaultIdentity; + } + } + if (typeSchema == null && oldListLength > 0) { + typeSchema = canReflect.getSchema(canReflect.getKeyValue(oldList, 0)); + } + if (typeSchema) { + return makeIdentityFromMapSchema(typeSchema); + } else { + return defaultIdentity; + } + } + function reverseDiff(oldDiffStopIndex, newDiffStopIndex, oldList, newList, identity) { + var oldIndex = oldList.length - 1, newIndex = newList.length - 1; + while (oldIndex > oldDiffStopIndex && newIndex > newDiffStopIndex) { + var oldItem = oldList[oldIndex], newItem = newList[newIndex]; + if (identity(oldItem, newItem, oldIndex)) { + oldIndex--; + newIndex--; + continue; + } else { + return [{ + type: 'splice', + index: newDiffStopIndex, + deleteCount: oldIndex - oldDiffStopIndex + 1, + insert: slice.call(newList, newDiffStopIndex, newIndex + 1) + }]; + } + } + return [{ + type: 'splice', + index: newDiffStopIndex, + deleteCount: oldIndex - oldDiffStopIndex + 1, + insert: slice.call(newList, newDiffStopIndex, newIndex + 1) + }]; + } + module.exports = function (oldList, newList, schemaOrIdentity) { + var oldIndex = 0, newIndex = 0, oldLength = canReflect.size(oldList), newLength = canReflect.size(newList), patches = []; + var schemaType = typeof schemaOrIdentity, identity; + if (schemaType === 'function') { + identity = schemaOrIdentity; + } else if (schemaOrIdentity != null) { + if (schemaOrIdentity.type === 'map') { + identity = makeIdentityFromMapSchema(schemaOrIdentity); + } else { + identity = makeIdentityFromListSchema(schemaOrIdentity); + } + } else { + identity = makeIdentity(oldList, oldLength); + } + while (oldIndex < oldLength && newIndex < newLength) { + var oldItem = oldList[oldIndex], newItem = newList[newIndex]; + if (identity(oldItem, newItem, oldIndex)) { + oldIndex++; + newIndex++; + continue; + } + if (newIndex + 1 < newLength && identity(oldItem, newList[newIndex + 1], oldIndex)) { + patches.push({ + index: newIndex, + deleteCount: 0, + insert: [newList[newIndex]], + type: 'splice' + }); + oldIndex++; + newIndex += 2; + continue; + } else if (oldIndex + 1 < oldLength && identity(oldList[oldIndex + 1], newItem, oldIndex + 1)) { + patches.push({ + index: newIndex, + deleteCount: 1, + insert: [], + type: 'splice' + }); + oldIndex += 2; + newIndex++; + continue; + } else { + patches.push.apply(patches, reverseDiff(oldIndex, newIndex, oldList, newList, identity)); + return patches; + } + } + if (newIndex === newLength && oldIndex === oldLength) { + return patches; + } + patches.push({ + type: 'splice', + index: newIndex, + deleteCount: oldLength - oldIndex, + insert: slice.call(newList, newIndex) + }); + return patches; + }; +}); +/*can-attribute-observable@1.1.7#behaviors*/ +define('can-attribute-observable@1.1.7#behaviors', [ + 'require', + 'exports', + 'module', + 'can-globals/document/document', + 'can-globals/global/global', + 'can-dom-data-state', + 'can-dom-events', + 'can-dom-mutate', + 'can-dom-mutate/node', + 'can-globals/mutation-observer/mutation-observer', + 'can-diff/list/list', + 'can-queues' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var getDocument = require('can-globals/document/document'); + var global = require('can-globals/global/global')(); + var setData = require('can-dom-data-state'); + var domEvents = require('can-dom-events'); + var domMutate = require('can-dom-mutate'); + var domMutateNode = require('can-dom-mutate/node'); + var getMutationObserver = require('can-globals/mutation-observer/mutation-observer'); + var diff = require('can-diff/list/list'); + var queues = require('can-queues'); + var formElements = { + 'INPUT': true, + 'TEXTAREA': true, + 'SELECT': true, + 'BUTTON': true + }, toString = function (value) { + if (value == null) { + return ''; + } else { + return '' + value; + } + }, isSVG = function (el) { + return el.namespaceURI === 'http://www.w3.org/2000/svg'; + }, truthy = function () { + return true; + }, getSpecialTest = function (special) { + return special && special.test || truthy; + }, propProp = function (prop, obj) { + obj = obj || {}; + obj.get = function () { + return this[prop]; + }; + obj.set = function (value) { + if (this[prop] !== value) { + this[prop] = value; + } + }; + return obj; + }, booleanProp = function (prop) { + return { + isBoolean: true, + set: function (value) { + if (prop in this) { + this[prop] = value; + } else { + domMutateNode.setAttribute.call(this, prop, ''); + } + }, + remove: function () { + this[prop] = false; + } + }; + }, setupMO = function (el, callback) { + var attrMO = setData.get.call(el, 'attrMO'); + if (!attrMO) { + var onMutation = function () { + callback.call(el); + }; + var MO = getMutationObserver(); + if (MO) { + var observer = new MO(onMutation); + observer.observe(el, { + childList: true, + subtree: true + }); + setData.set.call(el, 'attrMO', observer); + } else { + setData.set.call(el, 'attrMO', true); + setData.set.call(el, 'canBindingCallback', { onMutation: onMutation }); + } + } + }, _findOptionToSelect = function (parent, value) { + var child = parent.firstChild; + while (child) { + if (child.nodeName === 'OPTION' && value === child.value) { + return child; + } + if (child.nodeName === 'OPTGROUP') { + var groupChild = _findOptionToSelect(child, value); + if (groupChild) { + return groupChild; + } + } + child = child.nextSibling; + } + }, setChildOptions = function (el, value) { + var option; + if (value != null) { + option = _findOptionToSelect(el, value); + } + if (option) { + option.selected = true; + } else { + el.selectedIndex = -1; + } + }, forEachOption = function (parent, fn) { + var child = parent.firstChild; + while (child) { + if (child.nodeName === 'OPTION') { + fn(child); + } + if (child.nodeName === 'OPTGROUP') { + forEachOption(child, fn); + } + child = child.nextSibling; + } + }, collectSelectedOptions = function (parent) { + var selectedValues = []; + forEachOption(parent, function (option) { + if (option.selected) { + selectedValues.push(option.value); + } + }); + return selectedValues; + }, markSelectedOptions = function (parent, values) { + forEachOption(parent, function (option) { + option.selected = values.indexOf(option.value) !== -1; + }); + }, setChildOptionsOnChange = function (select, aEL) { + var handler = setData.get.call(select, 'attrSetChildOptions'); + if (handler) { + return Function.prototype; + } + handler = function () { + setChildOptions(select, select.value); + }; + setData.set.call(select, 'attrSetChildOptions', handler); + aEL.call(select, 'change', handler); + return function (rEL) { + setData.clean.call(select, 'attrSetChildOptions'); + rEL.call(select, 'change', handler); + }; + }, behaviorRules = new Map(), isPropWritable = function (el, prop) { + var desc = Object.getOwnPropertyDescriptor(el, prop); + if (desc) { + return desc.writable || desc.set; + } else { + var proto = Object.getPrototypeOf(el); + if (proto) { + return isPropWritable(proto, prop); + } + } + return false; + }, cacheRule = function (el, attrOrPropName, rule) { + var rulesForElementType; + rulesForElementType = behaviorRules.get(el.prototype); + if (!rulesForElementType) { + rulesForElementType = {}; + behaviorRules.set(el.constructor, rulesForElementType); + } + rulesForElementType[attrOrPropName] = rule; + return rule; + }; + var specialAttributes = { + checked: { + get: function () { + return this.checked; + }, + set: function (val) { + var notFalse = !!val || val === '' || arguments.length === 0; + this.checked = notFalse; + if (notFalse && this.type === 'radio') { + this.defaultChecked = true; + } + }, + remove: function () { + this.checked = false; + }, + test: function () { + return this.nodeName === 'INPUT'; + } + }, + 'class': { + get: function () { + if (isSVG(this)) { + return this.getAttribute('class'); + } + return this.className; + }, + set: function (val) { + val = val || ''; + if (isSVG(this)) { + domMutateNode.setAttribute.call(this, 'class', '' + val); + } else { + this.className = val; + } + } + }, + disabled: booleanProp('disabled'), + focused: { + get: function () { + return this === document.activeElement; + }, + set: function (val) { + var cur = attr.get(this, 'focused'); + var docEl = this.ownerDocument.documentElement; + var element = this; + function focusTask() { + if (val) { + element.focus(); + } else { + element.blur(); + } + } + if (cur !== val) { + if (!docEl.contains(element)) { + var insertionDisposal = domMutate.onNodeInsertion(element, function () { + insertionDisposal(); + focusTask(); + }); + } else { + queues.enqueueByQueue({ mutate: [focusTask] }, null, []); + } + } + return true; + }, + addEventListener: function (eventName, handler, aEL) { + aEL.call(this, 'focus', handler); + aEL.call(this, 'blur', handler); + return function (rEL) { + rEL.call(this, 'focus', handler); + rEL.call(this, 'blur', handler); + }; + }, + test: function () { + return this.nodeName === 'INPUT'; + } + }, + 'for': propProp('htmlFor'), + innertext: propProp('innerText'), + innerhtml: propProp('innerHTML'), + innerHTML: propProp('innerHTML', { + addEventListener: function (eventName, handler, aEL) { + var handlers = []; + var el = this; + [ + 'change', + 'blur' + ].forEach(function (eventName) { + var localHandler = function () { + handler.apply(this, arguments); + }; + domEvents.addEventListener(el, eventName, localHandler); + handlers.push([ + eventName, + localHandler + ]); + }); + return function (rEL) { + handlers.forEach(function (info) { + rEL.call(el, info[0], info[1]); + }); + }; + } + }), + required: booleanProp('required'), + readonly: booleanProp('readOnly'), + selected: { + get: function () { + return this.selected; + }, + set: function (val) { + val = !!val; + setData.set.call(this, 'lastSetValue', val); + this.selected = val; + }, + addEventListener: function (eventName, handler, aEL) { + var option = this; + var select = this.parentNode; + var lastVal = option.selected; + var localHandler = function (changeEvent) { + var curVal = option.selected; + lastVal = setData.get.call(option, 'lastSetValue') || lastVal; + if (curVal !== lastVal) { + lastVal = curVal; + domEvents.dispatch(option, eventName); + } + }; + var removeChangeHandler = setChildOptionsOnChange(select, aEL); + domEvents.addEventListener(select, 'change', localHandler); + aEL.call(option, eventName, handler); + return function (rEL) { + removeChangeHandler(rEL); + domEvents.removeEventListener(select, 'change', localHandler); + rEL.call(option, eventName, handler); + }; + }, + test: function () { + return this.nodeName === 'OPTION' && this.parentNode && this.parentNode.nodeName === 'SELECT'; + } + }, + style: { + set: function () { + var el = global.document && getDocument().createElement('div'); + if (el && el.style && 'cssText' in el.style) { + return function (val) { + this.style.cssText = val || ''; + }; + } else { + return function (val) { + domMutateNode.setAttribute.call(this, 'style', val); + }; + } + }() + }, + textcontent: propProp('textContent'), + value: { + get: function () { + var value = this.value; + if (this.nodeName === 'SELECT') { + if ('selectedIndex' in this && this.selectedIndex === -1) { + value = undefined; + } + } + return value; + }, + set: function (value) { + var nodeName = this.nodeName.toLowerCase(); + if (nodeName === 'input') { + value = toString(value); + } + if (this.value !== value || nodeName === 'option') { + this.value = value; + } + if (nodeName === 'input' || nodeName === 'textarea') { + this.defaultValue = value; + } + if (nodeName === 'select') { + setData.set.call(this, 'attrValueLastVal', value); + setChildOptions(this, value === null ? value : this.value); + var docEl = this.ownerDocument.documentElement; + if (!docEl.contains(this)) { + var select = this; + var insertionDisposal = domMutate.onNodeInsertion(select, function () { + insertionDisposal(); + setChildOptions(select, value === null ? value : select.value); + }); + } + setupMO(this, function () { + var value = setData.get.call(this, 'attrValueLastVal'); + attr.set(this, 'value', value); + domEvents.dispatch(this, 'change'); + }); + } + }, + test: function () { + return formElements[this.nodeName]; + } + }, + values: { + get: function () { + return collectSelectedOptions(this); + }, + set: function (values) { + values = values || []; + markSelectedOptions(this, values); + setData.set.call(this, 'stickyValues', attr.get(this, 'values')); + setupMO(this, function () { + var previousValues = setData.get.call(this, 'stickyValues'); + attr.set(this, 'values', previousValues); + var currentValues = setData.get.call(this, 'stickyValues'); + var changes = diff(previousValues.slice().sort(), currentValues.slice().sort()); + if (changes.length) { + domEvents.dispatch(this, 'values'); + } + }); + }, + addEventListener: function (eventName, handler, aEL) { + var localHandler = function () { + domEvents.dispatch(this, 'values'); + }; + domEvents.addEventListener(this, 'change', localHandler); + aEL.call(this, eventName, handler); + return function (rEL) { + domEvents.removeEventListener(this, 'change', localHandler); + rEL.call(this, eventName, handler); + }; + } + } + }; + var attr = { + rules: behaviorRules, + specialAttributes: specialAttributes, + getRule: function (el, attrOrPropName) { + var special = specialAttributes[attrOrPropName]; + if (special) { + return special; + } + var rulesForElementType = behaviorRules.get(el.constructor); + var cached = rulesForElementType && rulesForElementType[attrOrPropName]; + if (cached) { + return cached; + } + if (!(attrOrPropName in el)) { + return this.attribute(attrOrPropName); + } + var newRule = isPropWritable(el, attrOrPropName) ? this.property(attrOrPropName) : this.attribute(attrOrPropName); + return cacheRule(el, attrOrPropName, newRule); + }, + attribute: function (attrName) { + return { + get: function () { + return this.getAttribute(attrName); + }, + set: function (val) { + domMutateNode.setAttribute.call(this, attrName, val); + } + }; + }, + property: function (propName) { + return { + get: function () { + return this[propName]; + }, + set: function (val) { + this[propName] = val; + } + }; + }, + findSpecialListener: function (attributeName) { + return specialAttributes[attributeName] && specialAttributes[attributeName].addEventListener; + }, + setAttrOrProp: function (el, attrName, val) { + return this.set(el, attrName, val); + }, + set: function (el, attrName, val) { + var rule = this.getRule(el, attrName); + var setter = rule && rule.set; + if (setter) { + return setter.call(el, val); + } + }, + get: function (el, attrName) { + var rule = this.getRule(el, attrName); + var getter = rule && rule.get; + if (getter) { + return rule.test ? rule.test.call(el) && getter.call(el) : getter.call(el); + } + }, + remove: function (el, attrName) { + attrName = attrName.toLowerCase(); + var special = specialAttributes[attrName]; + var setter = special && special.set; + var remover = special && special.remove; + var test = getSpecialTest(special); + if (typeof remover === 'function' && test.call(el)) { + remover.call(el); + } else if (typeof setter === 'function' && test.call(el)) { + setter.call(el, undefined); + } else { + domMutateNode.removeAttribute.call(el, attrName); + } + } + }; + module.exports = attr; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-view-live@4.2.7#lib/attr*/ +define('can-view-live@4.2.7#lib/attr', [ + 'require', + 'exports', + 'module', + './core', + 'can-reflect', + 'can-queues', + 'can-attribute-observable/behaviors' +], function (require, exports, module) { + 'use strict'; + var live = require('./core'); + var canReflect = require('can-reflect'); + var queues = require('can-queues'); + var attr = require('can-attribute-observable/behaviors'); + live.attr = function (el, attributeName, compute) { + function liveUpdateAttr(newVal) { + queues.domUIQueue.enqueue(attr.set, attr, [ + el, + attributeName, + newVal + ]); + } + live.listen(el, compute, liveUpdateAttr); + attr.set(el, attributeName, canReflect.getValue(compute)); + }; +}); +/*can-view-live@4.2.7#lib/attrs*/ +define('can-view-live@4.2.7#lib/attrs', [ + 'require', + 'exports', + 'module', + './core', + 'can-view-callbacks', + 'can-dom-mutate', + 'can-dom-mutate/node', + 'can-reflect', + 'can-reflect-dependencies' +], function (require, exports, module) { + 'use strict'; + var live = require('./core'); + var viewCallbacks = require('can-view-callbacks'); + var domMutate = require('can-dom-mutate'); + var domMutateNode = require('can-dom-mutate/node'); + var canReflect = require('can-reflect'); + var canReflectDeps = require('can-reflect-dependencies'); + live.attrs = function (el, compute, scope, options) { + if (!canReflect.isObservableLike(compute)) { + var attrs = live.getAttributeParts(compute); + for (var name in attrs) { + domMutateNode.setAttribute.call(el, name, attrs[name]); + } + return; + } + var oldAttrs = {}; + function liveAttrsUpdate(newVal) { + var newAttrs = live.getAttributeParts(newVal), name; + for (name in newAttrs) { + var newValue = newAttrs[name], oldValue = oldAttrs[name]; + if (newValue !== oldValue) { + domMutateNode.setAttribute.call(el, name, newValue); + var callback = viewCallbacks.attr(name); + if (callback) { + callback(el, { + attributeName: name, + scope: scope, + options: options + }); + } + } + delete oldAttrs[name]; + } + for (name in oldAttrs) { + domMutateNode.removeAttribute.call(el, name); + } + oldAttrs = newAttrs; + } + canReflect.onValue(compute, liveAttrsUpdate, 'domUI'); + var removalDisposal; + var teardownHandler = function () { + canReflect.offValue(compute, liveAttrsUpdate, 'domUI'); + if (removalDisposal) { + removalDisposal(); + removalDisposal = undefined; + } + }; + removalDisposal = domMutate.onNodeRemoval(el, function () { + var doc = el.ownerDocument; + var ownerNode = doc.contains ? doc : doc.documentElement; + if (!ownerNode.contains(el)) { + teardownHandler(); + } + }); + liveAttrsUpdate(canReflect.getValue(compute)); + }; +}); +/*can-view-live@4.2.7#lib/html*/ +define('can-view-live@4.2.7#lib/html', [ + 'require', + 'exports', + 'module', + './core', + 'can-view-nodelist', + 'can-fragment', + 'can-child-nodes', + 'can-reflect', + 'can-symbol', + 'can-queues' +], function (require, exports, module) { + 'use strict'; + var live = require('./core'); + var nodeLists = require('can-view-nodelist'); + var makeFrag = require('can-fragment'); + var childNodes = require('can-child-nodes'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var queues = require('can-queues'); + var viewInsertSymbol = canSymbol.for('can.viewInsert'); + function updateNodeList(data, frag, nodeListUpdatedByFn) { + if (data.nodeList.isUnregistered !== true) { + var newChildren = canReflect.toArray(childNodes(frag)); + if (!nodeListUpdatedByFn) { + nodeLists.update(data.nodeList, newChildren, data.oldNodes); + } + var oldNodes = data.oldNodes; + data.oldNodes = newChildren; + nodeLists.replace(oldNodes, frag); + } + } + live.html = function (el, compute, parentNode, nodeListOrOptions) { + var data; + var makeAndPut; + var nodeList; + var nodes; + var options; + if (nodeListOrOptions !== undefined) { + if (Array.isArray(nodeListOrOptions)) { + nodeList = nodeListOrOptions; + } else { + nodeList = nodeListOrOptions.nodeList; + options = nodeListOrOptions; + } + } + var meta = { reasonLog: 'live.html replace::' + canReflect.getName(compute) }; + parentNode = live.getParentNode(el, parentNode); + function liveHTMLUpdateHTML(newVal) { + var attached = nodeLists.first(nodes).parentNode; + if (attached) { + makeAndPut(newVal, true); + } + var pn = nodeLists.first(nodes).parentNode; + data.teardownCheck(pn); + } + data = live.listen(parentNode, compute, liveHTMLUpdateHTML); + nodes = nodeList || [el]; + makeAndPut = function (val, useQueue) { + if (val && typeof val[viewInsertSymbol] === 'function') { + val = val[viewInsertSymbol](options); + } + var isFunction = typeof val === 'function'; + var frag = makeFrag(isFunction ? '' : val); + live.addTextNodeIfNoChildren(frag); + if (useQueue === true) { + data.oldNodes = nodeLists.unregisterChildren(nodes, true); + var nodeListUpdatedByFn = false; + if (isFunction) { + val(frag.firstChild); + nodeListUpdatedByFn = nodeLists.first(nodes) === frag.firstChild; + } + queues.domUIQueue.enqueue(updateNodeList, null, [ + data, + frag, + nodeListUpdatedByFn + ], meta); + } else { + data.oldNodes = nodeLists.update(nodes, childNodes(frag)); + if (isFunction) { + val(frag.firstChild); + } + nodeLists.replace(data.oldNodes, frag); + } + }; + data.nodeList = nodes; + if (!nodeList) { + nodeLists.register(nodes, data.teardownCheck); + } else { + nodeList.unregistered = data.teardownCheck; + } + makeAndPut(canReflect.getValue(compute)); + }; +}); +/*can-view-live@4.2.7#lib/set-observable*/ +define('can-view-live@4.2.7#lib/set-observable', [ + 'require', + 'exports', + 'module', + 'can-simple-observable', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var SimpleObservable = require('can-simple-observable'); + var canReflect = require('can-reflect'); + function SetObservable(initialValue, setter) { + this.setter = setter; + SimpleObservable.call(this, initialValue); + } + SetObservable.prototype = Object.create(SimpleObservable.prototype); + SetObservable.prototype.constructor = SetObservable; + SetObservable.prototype.set = function (newVal) { + this.setter(newVal); + }; + canReflect.assignSymbols(SetObservable.prototype, { 'can.setValue': SetObservable.prototype.set }); + module.exports = SetObservable; +}); +/*can-diff@1.4.2#patcher/patcher*/ +define('can-diff@1.4.2#patcher/patcher', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-key-tree', + 'can-symbol', + '../list/list', + 'can-queues', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var KeyTree = require('can-key-tree'); + var canSymbol = require('can-symbol'); + var diff = require('../list/list'); + var queues = require('can-queues'); + var canSymbol = require('can-symbol'); + var onValueSymbol = canSymbol.for('can.onValue'), offValueSymbol = canSymbol.for('can.offValue'); + var onPatchesSymbol = canSymbol.for('can.onPatches'); + var offPatchesSymbol = canSymbol.for('can.offPatches'); + var Patcher = function (observableOrList, priority) { + this.handlers = new KeyTree([ + Object, + Array + ], { + onFirst: this.setup.bind(this), + onEmpty: this.teardown.bind(this) + }); + this.observableOrList = observableOrList; + this.isObservableValue = canReflect.isValueLike(this.observableOrList) || canReflect.isObservableLike(this.observableOrList); + if (this.isObservableValue) { + this.priority = canReflect.getPriority(observableOrList); + } else { + this.priority = priority || 0; + } + this.onList = this.onList.bind(this); + this.onPatchesNotify = this.onPatchesNotify.bind(this); + this.onPatchesDerive = this.onPatchesDerive.bind(this); + this.patches = []; + }; + Patcher.prototype = { + constructor: Patcher, + setup: function () { + if (this.observableOrList[onValueSymbol]) { + canReflect.onValue(this.observableOrList, this.onList, 'notify'); + this.setupList(canReflect.getValue(this.observableOrList)); + } else { + this.setupList(this.observableOrList); + } + }, + teardown: function () { + if (this.observableOrList[offValueSymbol]) { + canReflect.offValue(this.observableOrList, this.onList, 'notify'); + } + }, + setupList: function (list) { + this.currentList = list; + if (list && list[onPatchesSymbol]) { + list[onPatchesSymbol](this.onPatchesNotify, 'notify'); + } + }, + onList: function onList(newList) { + var current = this.currentList || []; + newList = newList || []; + if (current[offPatchesSymbol]) { + current[offPatchesSymbol](this.onPatchesNotify, 'notify'); + } + var patches = diff(current, newList); + this.currentList = newList; + this.onPatchesNotify(patches); + if (newList[onPatchesSymbol]) { + newList[onPatchesSymbol](this.onPatchesNotify, 'notify'); + } + }, + onPatchesNotify: function onPatchesNotify(patches) { + this.patches.push.apply(this.patches, patches); + queues.deriveQueue.enqueue(this.onPatchesDerive, this, [], { priority: this.priority }); + }, + onPatchesDerive: function onPatchesDerive() { + var patches = this.patches; + this.patches = []; + queues.enqueueByQueue(this.handlers.getNode([]), this.currentList, [ + patches, + this.currentList + ], null, [ + 'Apply patches', + patches + ]); + } + }; + canReflect.assignSymbols(Patcher.prototype, { + 'can.onPatches': function (handler, queue) { + this.handlers.add([ + queue || 'mutate', + handler + ]); + }, + 'can.offPatches': function (handler, queue) { + this.handlers.delete([ + queue || 'mutate', + handler + ]); + } + }); + module.exports = Patcher; +}); +/*can-view-live@4.2.7#lib/list*/ +define('can-view-live@4.2.7#lib/list', [ + 'require', + 'exports', + 'module', + './core', + 'can-view-nodelist', + 'can-fragment', + 'can-child-nodes', + 'can-dom-mutate/node', + 'can-reflect', + 'can-symbol', + 'can-reflect-dependencies', + 'can-simple-observable', + './set-observable', + 'can-diff/patcher/patcher' +], function (require, exports, module) { + 'use strict'; + var live = require('./core'); + var nodeLists = require('can-view-nodelist'); + var frag = require('can-fragment'); + var childNodes = require('can-child-nodes'); + var domMutateNode = require('can-dom-mutate/node'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var canReflectDeps = require('can-reflect-dependencies'); + var SimpleObservable = require('can-simple-observable'); + var SetObservable = require('./set-observable'); + var Patcher = require('can-diff/patcher/patcher'); + var splice = [].splice; + var renderAndAddToNodeLists = function (newNodeLists, parentNodeList, render, context, args) { + var itemNodeList = []; + if (parentNodeList) { + nodeLists.register(itemNodeList, null, true, true); + itemNodeList.parentList = parentNodeList; + itemNodeList.expression = '#each SUBEXPRESSION'; + } + var itemHTML = render.apply(context, args.concat([itemNodeList])), itemFrag = frag(itemHTML); + var children = canReflect.toArray(childNodes(itemFrag)); + if (parentNodeList) { + nodeLists.update(itemNodeList, children); + newNodeLists.push(itemNodeList); + } else { + newNodeLists.push(nodeLists.register(children)); + } + return itemFrag; + }, removeFromNodeList = function (masterNodeList, index, length) { + var removedMappings = masterNodeList.splice(index + 1, length), itemsToRemove = []; + removedMappings.forEach(function (nodeList) { + var nodesToRemove = nodeLists.unregister(nodeList); + [].push.apply(itemsToRemove, nodesToRemove); + }); + return itemsToRemove; + }; + var onPatchesSymbol = canSymbol.for('can.onPatches'); + var offPatchesSymbol = canSymbol.for('can.offPatches'); + function ListDOMPatcher(el, compute, render, context, parentNode, nodeList, falseyRender) { + this.patcher = new Patcher(compute); + parentNode = live.getParentNode(el, parentNode); + this.value = compute; + this.render = render; + this.context = context; + this.parentNode = parentNode; + this.falseyRender = falseyRender; + this.masterNodeList = nodeList || nodeLists.register([el], null, true); + this.placeholder = el; + this.indexMap = []; + this.isValueLike = canReflect.isValueLike(this.value); + this.isObservableLike = canReflect.isObservableLike(this.value); + this.onPatches = this.onPatches.bind(this); + var data = this.data = live.setup(parentNode, this.setupValueBinding.bind(this), this.teardownValueBinding.bind(this)); + this.masterNodeList.unregistered = function () { + data.teardownCheck(); + }; + } + var onPatchesSymbol = canSymbol.for('can.onPatches'); + var offPatchesSymbol = canSymbol.for('can.offPatches'); + ListDOMPatcher.prototype = { + setupValueBinding: function () { + this.patcher[onPatchesSymbol](this.onPatches, 'domUI'); + if (this.patcher.currentList && this.patcher.currentList.length) { + this.onPatches([{ + insert: this.patcher.currentList, + index: 0, + deleteCount: 0 + }]); + } else { + this.addFalseyIfEmpty(); + } + }, + teardownValueBinding: function () { + this.patcher[offPatchesSymbol](this.onPatches, 'domUI'); + this.exit = true; + this.remove({ length: this.patcher.currentList ? this.patcher.currentList.length : 0 }, 0, true); + }, + onPatches: function ListDOMPatcher_onPatches(patches) { + if (this.exit) { + return; + } + for (var i = 0, patchLen = patches.length; i < patchLen; i++) { + var patch = patches[i]; + if (patch.type === 'move') { + this.move(patch.toIndex, patch.fromIndex); + } else { + if (patch.deleteCount) { + this.remove({ length: patch.deleteCount }, patch.index, true); + } + if (patch.insert && patch.insert.length) { + this.add(patch.insert, patch.index); + } + } + } + }, + add: function (items, index) { + var frag = this.placeholder.ownerDocument.createDocumentFragment(), newNodeLists = [], newIndicies = [], masterNodeList = this.masterNodeList, render = this.render, context = this.context; + items.forEach(function (item, key) { + var itemIndex = new SimpleObservable(key + index), itemCompute = new SetObservable(item, function (newVal) { + canReflect.setKeyValue(this.patcher.currentList, itemIndex.get(), newVal); + }.bind(this)), itemFrag = renderAndAddToNodeLists(newNodeLists, masterNodeList, render, context, [ + itemCompute, + itemIndex + ]); + frag.appendChild(itemFrag); + newIndicies.push(itemIndex); + }, this); + var masterListIndex = index + 1; + if (!this.indexMap.length) { + var falseyItemsToRemove = removeFromNodeList(masterNodeList, 0, masterNodeList.length - 1); + nodeLists.remove(falseyItemsToRemove); + } + if (!masterNodeList[masterListIndex]) { + nodeLists.after(masterListIndex === 1 ? [this.placeholder] : [nodeLists.last(this.masterNodeList[masterListIndex - 1])], frag); + } else { + var el = nodeLists.first(masterNodeList[masterListIndex]); + domMutateNode.insertBefore.call(el.parentNode, frag, el); + } + splice.apply(this.masterNodeList, [ + masterListIndex, + 0 + ].concat(newNodeLists)); + splice.apply(this.indexMap, [ + index, + 0 + ].concat(newIndicies)); + for (var i = index + newIndicies.length, len = this.indexMap.length; i < len; i++) { + this.indexMap[i].set(i); + } + }, + remove: function (items, index) { + if (index < 0) { + index = this.indexMap.length + index; + } + var itemsToRemove = removeFromNodeList(this.masterNodeList, index, items.length); + var indexMap = this.indexMap; + indexMap.splice(index, items.length); + for (var i = index, len = indexMap.length; i < len; i++) { + indexMap[i].set(i); + } + if (!this.exit) { + this.addFalseyIfEmpty(); + nodeLists.remove(itemsToRemove); + } else { + nodeLists.unregister(this.masterNodeList); + } + }, + addFalseyIfEmpty: function () { + if (this.falseyRender && this.indexMap.length === 0) { + var falseyNodeLists = []; + var falseyFrag = renderAndAddToNodeLists(falseyNodeLists, this.masterNodeList, this.falseyRender, this.currentList, [this.currentList]); + nodeLists.after([this.masterNodeList[0]], falseyFrag); + this.masterNodeList.push(falseyNodeLists[0]); + } + }, + move: function move(newIndex, currentIndex) { + newIndex = newIndex + 1; + currentIndex = currentIndex + 1; + var masterNodeList = this.masterNodeList, indexMap = this.indexMap; + var referenceNodeList = masterNodeList[newIndex]; + var movedElements = frag(nodeLists.flatten(masterNodeList[currentIndex])); + var referenceElement; + if (currentIndex < newIndex) { + referenceElement = nodeLists.last(referenceNodeList).nextSibling; + } else { + referenceElement = nodeLists.first(referenceNodeList); + } + var parentNode = masterNodeList[0].parentNode; + parentNode.insertBefore(movedElements, referenceElement); + var temp = masterNodeList[currentIndex]; + [].splice.apply(masterNodeList, [ + currentIndex, + 1 + ]); + [].splice.apply(masterNodeList, [ + newIndex, + 0, + temp + ]); + newIndex = newIndex - 1; + currentIndex = currentIndex - 1; + var indexCompute = indexMap[currentIndex]; + [].splice.apply(indexMap, [ + currentIndex, + 1 + ]); + [].splice.apply(indexMap, [ + newIndex, + 0, + indexCompute + ]); + var i = Math.min(currentIndex, newIndex); + var len = indexMap.length; + for (i, len; i < len; i++) { + indexMap[i].set(i); + } + }, + set: function (newVal, index) { + this.remove({ length: 1 }, index, true); + this.add([newVal], index); + } + }; + live.list = function (el, list, render, context, parentNode, nodeList, falseyRender) { + if (el.nodeType !== Node.TEXT_NODE) { + var textNode; + if (!nodeList) { + textNode = document.createTextNode(''); + el.parentNode.replaceChild(textNode, el); + el = textNode; + } else { + textNode = document.createTextNode(''); + nodeLists.replace(nodeList, textNode); + nodeLists.update(nodeList, [textNode]); + el = textNode; + } + } + new ListDOMPatcher(el, list, render, context, parentNode, nodeList, falseyRender); + }; +}); +/*can-view-live@4.2.7#lib/text*/ +define('can-view-live@4.2.7#lib/text', [ + 'require', + 'exports', + 'module', + './core', + 'can-view-nodelist', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var live = require('./core'); + var nodeLists = require('can-view-nodelist'); + var canReflect = require('can-reflect'); + live.text = function (el, compute, parentNode, nodeList) { + if (el.nodeType !== Node.TEXT_NODE) { + var textNode; + if (!nodeList) { + textNode = document.createTextNode(''); + el.parentNode.replaceChild(textNode, el); + el = textNode; + } else { + textNode = document.createTextNode(''); + nodeLists.replace(nodeList, textNode); + nodeLists.update(nodeList, [textNode]); + el = textNode; + } + } + var parent = live.getParentNode(el, parentNode); + el.nodeValue = live.makeString(canReflect.getValue(compute)); + function liveTextUpdateTextNode(newVal) { + el.nodeValue = live.makeString(newVal); + } + var data = live.listen(parent, compute, liveTextUpdateTextNode, 'domUI'); + if (!nodeList) { + nodeList = nodeLists.register([el], null, true); + } + nodeList.unregistered = data.teardownCheck; + data.nodeList = nodeList; + }; +}); +/*can-view-live@4.2.7#can-view-live*/ +define('can-view-live@4.2.7#can-view-live', [ + 'require', + 'exports', + 'module', + './lib/core', + './lib/attr', + './lib/attrs', + './lib/html', + './lib/list', + './lib/text' +], function (require, exports, module) { + 'use strict'; + var live = require('./lib/core'); + require('./lib/attr'); + require('./lib/attrs'); + require('./lib/html'); + require('./lib/list'); + require('./lib/text'); + module.exports = live; +}); +/*can-stache@4.15.9#src/text_section*/ +define('can-stache@4.15.9#src/text_section', [ + 'require', + 'exports', + 'module', + 'can-view-live', + './utils', + 'can-dom-mutate/node', + 'can-assign', + 'can-reflect', + 'can-observation' +], function (require, exports, module) { + 'use strict'; + var live = require('can-view-live'); + var utils = require('./utils'); + var domMutate = require('can-dom-mutate/node'); + var assign = require('can-assign'); + var canReflect = require('can-reflect'); + var Observation = require('can-observation'); + var noop = function () { + }; + var TextSectionBuilder = function (filename) { + if (filename) { + this.filename = filename; + } + this.stack = [new TextSection()]; + }; + assign(TextSectionBuilder.prototype, utils.mixins); + assign(TextSectionBuilder.prototype, { + startSection: function (process) { + var subSection = new TextSection(); + this.last().add({ + process: process, + truthy: subSection + }); + this.stack.push(subSection); + }, + endSection: function () { + this.stack.pop(); + }, + inverse: function () { + this.stack.pop(); + var falseySection = new TextSection(); + this.last().last().falsey = falseySection; + this.stack.push(falseySection); + }, + compile: function (state) { + var renderer = this.stack[0].compile(); + return function (scope) { + function textSectionRender() { + return renderer(scope); + } + var observation = new Observation(textSectionRender, null, { isObservable: false }); + canReflect.onValue(observation, noop); + var value = canReflect.getValue(observation); + if (canReflect.valueHasDependencies(observation)) { + if (state.textContentOnly) { + live.text(this, observation); + } else if (state.attr) { + live.attr(this, state.attr, observation); + } else { + live.attrs(this, observation, scope); + } + canReflect.offValue(observation, noop); + } else { + if (state.textContentOnly) { + this.nodeValue = value; + } else if (state.attr) { + domMutate.setAttribute.call(this, state.attr, value); + } else { + live.attrs(this, value); + } + } + }; + } + }); + var passTruthyFalsey = function (process, truthy, falsey) { + return function (scope) { + return process.call(this, scope, truthy, falsey); + }; + }; + var TextSection = function () { + this.values = []; + }; + assign(TextSection.prototype, { + add: function (data) { + this.values.push(data); + }, + last: function () { + return this.values[this.values.length - 1]; + }, + compile: function () { + var values = this.values, len = values.length; + for (var i = 0; i < len; i++) { + var value = this.values[i]; + if (typeof value === 'object') { + values[i] = passTruthyFalsey(value.process, value.truthy && value.truthy.compile(), value.falsey && value.falsey.compile()); + } + } + return function (scope) { + var txt = '', value; + for (var i = 0; i < len; i++) { + value = values[i]; + txt += typeof value === 'string' ? value : value.call(this, scope); + } + return txt; + }; + } + }); + module.exports = TextSectionBuilder; +}); +/*can-stache@4.15.9#expressions/arg*/ +define('can-stache@4.15.9#expressions/arg', function (require, exports, module) { + 'use strict'; + var Arg = function (expression, modifiers) { + this.expr = expression; + this.modifiers = modifiers || {}; + this.isCompute = false; + }; + Arg.prototype.value = function () { + return this.expr.value.apply(this.expr, arguments); + }; + module.exports = Arg; +}); +/*can-stache@4.15.9#expressions/literal*/ +define('can-stache@4.15.9#expressions/literal', function (require, exports, module) { + 'use strict'; + var Literal = function (value) { + this._value = value; + }; + Literal.prototype.value = function () { + return this._value; + }; + module.exports = Literal; +}); +/*can-simple-observable@2.4.1#setter/setter*/ +define('can-simple-observable@2.4.1#setter/setter', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-observation', + '../settable/settable', + 'can-event-queue/value/value' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var Observation = require('can-observation'); + var SettableObservable = require('../settable/settable'); + var valueEventBindings = require('can-event-queue/value/value'); + function SetterObservable(getter, setter) { + this.setter = setter; + this.observation = new Observation(getter); + this.handler = this.handler.bind(this); + } + SetterObservable.prototype = Object.create(SettableObservable.prototype); + SetterObservable.prototype.constructor = SetterObservable; + SetterObservable.prototype.set = function (newVal) { + this.setter(newVal); + }; + SetterObservable.prototype.hasDependencies = function () { + return canReflect.valueHasDependencies(this.observation); + }; + canReflect.assignSymbols(SetterObservable.prototype, { + 'can.setValue': SetterObservable.prototype.set, + 'can.valueHasDependencies': SetterObservable.prototype.hasDependencies + }); + module.exports = SetterObservable; +}); +/*can-stache@4.15.9#src/expression-helpers*/ +define('can-stache@4.15.9#src/expression-helpers', [ + 'require', + 'exports', + 'module', + '../expressions/arg', + '../expressions/literal', + 'can-reflect', + 'can-stache-key', + 'can-symbol', + 'can-observation', + 'can-view-scope/make-compute-like', + 'can-simple-observable/setter/setter' +], function (require, exports, module) { + 'use strict'; + var Arg = require('../expressions/arg'); + var Literal = require('../expressions/literal'); + var canReflect = require('can-reflect'); + var stacheKey = require('can-stache-key'); + var canSymbol = require('can-symbol'); + var Observation = require('can-observation'); + var makeComputeLike = require('can-view-scope/make-compute-like'); + var SetterObservable = require('can-simple-observable/setter/setter'); + function getObservableValue_fromKey(key, scope, readOptions) { + var data = scope.computeData(key, readOptions); + Observation.temporarilyBind(data); + return data; + } + function computeHasDependencies(compute) { + return compute[canSymbol.for('can.valueHasDependencies')] ? canReflect.valueHasDependencies(compute) : compute.computeInstance.hasDependencies; + } + function getObservableValue_fromDynamicKey_fromObservable(key, root, helperOptions, readOptions) { + var getKeys = function () { + return stacheKey.reads(('' + canReflect.getValue(key)).replace(/\./g, '\\.')); + }; + var parentHasKey; + var computeValue = new SetterObservable(function getDynamicKey() { + var readData = stacheKey.read(canReflect.getValue(root), getKeys()); + parentHasKey = readData.parentHasKey; + return readData.value; + }, function setDynamicKey(newVal) { + stacheKey.write(canReflect.getValue(root), getKeys(), newVal); + }); + Observation.temporarilyBind(computeValue); + computeValue.initialValue = canReflect.getValue(computeValue); + computeValue.parentHasKey = parentHasKey; + return computeValue; + } + function convertToArgExpression(expr) { + if (!(expr instanceof Arg) && !(expr instanceof Literal)) { + return new Arg(expr); + } else { + return expr; + } + } + function toComputeOrValue(value) { + if (canReflect.isObservableLike(value)) { + if (canReflect.isValueLike(value) && canReflect.valueHasDependencies(value) === false) { + return canReflect.getValue(value); + } + if (value.compute) { + return value.compute; + } else { + return makeComputeLike(value); + } + } + return value; + } + function toCompute(value) { + if (value) { + if (value.isComputed) { + return value; + } + if (value.compute) { + return value.compute; + } else { + return makeComputeLike(value); + } + } + return value; + } + module.exports = { + getObservableValue_fromKey: getObservableValue_fromKey, + computeHasDependencies: computeHasDependencies, + getObservableValue_fromDynamicKey_fromObservable: getObservableValue_fromDynamicKey_fromObservable, + convertToArgExpression: convertToArgExpression, + toComputeOrValue: toComputeOrValue, + toCompute: toCompute + }; +}); +/*can-stache@4.15.9#expressions/hashes*/ +define('can-stache@4.15.9#expressions/hashes', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-observation', + '../src/expression-helpers' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var Observation = require('can-observation'); + var expressionHelpers = require('../src/expression-helpers'); + var Hashes = function (hashes) { + this.hashExprs = hashes; + }; + Hashes.prototype.value = function (scope, helperOptions) { + var hash = {}; + for (var prop in this.hashExprs) { + var val = expressionHelpers.convertToArgExpression(this.hashExprs[prop]), value = val.value.apply(val, arguments); + hash[prop] = { + call: !val.modifiers || !val.modifiers.compute, + value: value + }; + } + return new Observation(function () { + var finalHash = {}; + for (var prop in hash) { + finalHash[prop] = hash[prop].call ? canReflect.getValue(hash[prop].value) : expressionHelpers.toComputeOrValue(hash[prop].value); + } + return finalHash; + }); + }; + module.exports = Hashes; +}); +/*can-stache@4.15.9#expressions/bracket*/ +define('can-stache@4.15.9#expressions/bracket', [ + 'require', + 'exports', + 'module', + '../src/expression-helpers' +], function (require, exports, module) { + 'use strict'; + var expressionHelpers = require('../src/expression-helpers'); + var Bracket = function (key, root, originalKey) { + this.root = root; + this.key = key; + }; + Bracket.prototype.value = function (scope, helpers) { + var root = this.root ? this.root.value(scope, helpers) : scope.peek('this'); + return expressionHelpers.getObservableValue_fromDynamicKey_fromObservable(this.key.value(scope, helpers), root, scope, helpers, {}); + }; + Bracket.prototype.closingTag = function () { + }; + module.exports = Bracket; +}); +/*can-stache@4.15.9#src/set-identifier*/ +define('can-stache@4.15.9#src/set-identifier', function (require, exports, module) { + 'use strict'; + module.exports = function SetIdentifier(value) { + this.value = value; + }; +}); +/*can-stache@4.15.9#expressions/call*/ +define('can-stache@4.15.9#expressions/call', [ + 'require', + 'exports', + 'module', + './hashes', + '../src/set-identifier', + 'can-symbol', + 'can-simple-observable/setter/setter', + '../src/expression-helpers', + 'can-reflect', + 'can-assign', + 'can-view-scope' +], function (require, exports, module) { + 'use strict'; + var Hashes = require('./hashes'); + var SetIdentifier = require('../src/set-identifier'); + var canSymbol = require('can-symbol'); + var SetterObservable = require('can-simple-observable/setter/setter'); + var expressionHelpers = require('../src/expression-helpers'); + var canReflect = require('can-reflect'); + var assign = require('can-assign'); + var sourceTextSymbol = canSymbol.for('can-stache.sourceText'); + var isViewSymbol = canSymbol.for('can.isView'); + var Scope = require('can-view-scope'); + var Call = function (methodExpression, argExpressions) { + this.methodExpr = methodExpression; + this.argExprs = argExpressions.map(expressionHelpers.convertToArgExpression); + }; + Call.prototype.args = function (scope, ignoreArgLookup) { + var hashExprs = {}; + var args = []; + var gotIgnoreFunction = typeof ignoreArgLookup === 'function'; + for (var i = 0, len = this.argExprs.length; i < len; i++) { + var arg = this.argExprs[i]; + if (arg.expr instanceof Hashes) { + assign(hashExprs, arg.expr.hashExprs); + } + if (!gotIgnoreFunction || !ignoreArgLookup(i)) { + var value = arg.value.apply(arg, arguments); + args.push({ + call: !arg.modifiers || !arg.modifiers.compute, + value: value + }); + } + } + return function (doNotWrapArguments) { + var finalArgs = []; + if (canReflect.size(hashExprs) > 0) { + finalArgs.hashExprs = hashExprs; + } + for (var i = 0, len = args.length; i < len; i++) { + if (doNotWrapArguments) { + finalArgs[i] = args[i].value; + } else { + finalArgs[i] = args[i].call ? canReflect.getValue(args[i].value) : expressionHelpers.toCompute(args[i].value); + } + } + return finalArgs; + }; + }; + Call.prototype.value = function (scope, helperOptions) { + var callExpression = this; + var method = this.methodExpr.value(scope, { proxyMethods: false }), func = canReflect.getValue(method); + var getArgs = callExpression.args(scope, func && func.ignoreArgLookup); + var computeFn = function (newVal) { + var func = canReflect.getValue(method); + if (typeof func === 'function') { + var args = getArgs(func.isLiveBound); + if (func.requiresOptionsArgument) { + if (args.hashExprs && helperOptions && helperOptions.exprData) { + helperOptions.exprData.hashExprs = args.hashExprs; + } + if (helperOptions !== undefined) { + args.push(helperOptions); + } + } + if (func[isViewSymbol] === true) { + if (!(args[0] instanceof Scope)) { + args[0] = scope.getTemplateContext().add(args[0]); + } + args.push(helperOptions.nodeList); + } + if (arguments.length) { + args.unshift(new SetIdentifier(newVal)); + } + return func.apply(method.thisArg || scope.peek('this'), args); + } + }; + if (helperOptions && helperOptions.doNotWrapInObservation) { + return computeFn(); + } else { + var computeValue = new SetterObservable(computeFn, computeFn); + return computeValue; + } + }; + Call.prototype.closingTag = function () { + return this.methodExpr.key; + }; + module.exports = Call; +}); +/*can-stache@4.15.9#expressions/helper*/ +define('can-stache@4.15.9#expressions/helper', [ + 'require', + 'exports', + 'module', + './literal', + './hashes', + 'can-assign', + 'can-log/dev/dev', + '../src/expression-helpers', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var Literal = require('./literal'); + var Hashes = require('./hashes'); + var assign = require('can-assign'); + var dev = require('can-log/dev/dev'); + var expressionHelpers = require('../src/expression-helpers'); + var canReflect = require('can-reflect'); + var Helper = function (methodExpression, argExpressions, hashExpressions) { + this.methodExpr = methodExpression; + this.argExprs = argExpressions; + this.hashExprs = hashExpressions; + this.mode = null; + }; + Helper.prototype.args = function (scope) { + var args = []; + for (var i = 0, len = this.argExprs.length; i < len; i++) { + var arg = this.argExprs[i]; + args.push(expressionHelpers.toComputeOrValue(arg.value.apply(arg, arguments))); + } + return args; + }; + Helper.prototype.hash = function (scope) { + var hash = {}; + for (var prop in this.hashExprs) { + var val = this.hashExprs[prop]; + hash[prop] = expressionHelpers.toComputeOrValue(val.value.apply(val, arguments)); + } + return hash; + }; + Helper.prototype.value = function (scope, helperOptions) { + var methodKey = this.methodExpr instanceof Literal ? '' + this.methodExpr._value : this.methodExpr.key, helperInstance = this, helperFn = expressionHelpers.getObservableValue_fromKey(methodKey, scope, { proxyMethods: false }), initialValue = helperFn && helperFn.initialValue, thisArg = helperFn && helperFn.thisArg; + if (typeof initialValue === 'function') { + helperFn = function helperFn() { + var args = helperInstance.args(scope), helperOptionArg = assign(assign({}, helperOptions), { + hash: helperInstance.hash(scope), + exprData: helperInstance + }); + args.push(helperOptionArg); + return initialValue.apply(thisArg || scope.peek('this'), args); + }; + } + return helperFn; + }; + Helper.prototype.closingTag = function () { + return this.methodExpr.key; + }; + if ("production" !== 'production') { + canReflect.assignSymbols(Helper.prototype, { + 'can.getName': function () { + return canReflect.getName(this.constructor) + '{{' + this.sourceText() + '}}'; + } + }); + } + module.exports = Helper; +}); +/*can-stache@4.15.9#expressions/lookup*/ +define('can-stache@4.15.9#expressions/lookup', [ + 'require', + 'exports', + 'module', + '../src/expression-helpers', + 'can-reflect', + 'can-symbol', + 'can-log/dev/dev', + 'can-stache-key' +], function (require, exports, module) { + 'use strict'; + var expressionHelpers = require('../src/expression-helpers'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var sourceTextSymbol = canSymbol.for('can-stache.sourceText'); + var dev = require('can-log/dev/dev'); + var observeReader = require('can-stache-key'); + var Lookup = function (key, root, sourceText) { + this.key = key; + this.rootExpr = root; + canReflect.setKeyValue(this, sourceTextSymbol, sourceText); + }; + Lookup.prototype.value = function (scope, readOptions) { + var value; + if (this.rootExpr) { + value = expressionHelpers.getObservableValue_fromDynamicKey_fromObservable(this.key, this.rootExpr.value(scope), scope, {}, {}); + } else { + value = expressionHelpers.getObservableValue_fromKey(this.key, scope, readOptions); + } + return value; + }; + module.exports = Lookup; +}); +/*can-stache@4.15.9#src/expression*/ +define('can-stache@4.15.9#src/expression', [ + 'require', + 'exports', + 'module', + '../expressions/arg', + '../expressions/literal', + '../expressions/hashes', + '../expressions/bracket', + '../expressions/call', + '../expressions/helper', + '../expressions/lookup', + './set-identifier', + '../src/expression-helpers', + './utils', + 'can-assign', + 'can-reflect', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var Arg = require('../expressions/arg'); + var Literal = require('../expressions/literal'); + var Hashes = require('../expressions/hashes'); + var Bracket = require('../expressions/bracket'); + var Call = require('../expressions/call'); + var Helper = require('../expressions/helper'); + var Lookup = require('../expressions/lookup'); + var SetIdentifier = require('./set-identifier'); + var expressionHelpers = require('../src/expression-helpers'); + var utils = require('./utils'); + var assign = require('can-assign'); + var last = utils.last; + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var sourceTextSymbol = canSymbol.for('can-stache.sourceText'); + var Hash = function () { + }; + var keyRegExp = /[\w\.\\\-_@\/\&%]+/, tokensRegExp = /('.*?'|".*?"|=|[\w\.\\\-_@\/*%\$]+|[\(\)]|,|\~|\[|\]\s*|\s*(?=\[))/g, bracketSpaceRegExp = /\]\s+/, literalRegExp = /^('.*?'|".*?"|-?[0-9]+\.?[0-9]*|true|false|null|undefined)$/; + var isTokenKey = function (token) { + return keyRegExp.test(token); + }; + var testDot = /^[\.@]\w/; + var isAddingToExpression = function (token) { + return isTokenKey(token) && testDot.test(token); + }; + var ensureChildren = function (type) { + if (!type.children) { + type.children = []; + } + return type; + }; + var Stack = function () { + this.root = { + children: [], + type: 'Root' + }; + this.current = this.root; + this.stack = [this.root]; + }; + assign(Stack.prototype, { + top: function () { + return last(this.stack); + }, + isRootTop: function () { + return this.top() === this.root; + }, + popTo: function (types) { + this.popUntil(types); + this.pop(); + }, + pop: function () { + if (!this.isRootTop()) { + this.stack.pop(); + } + }, + first: function (types) { + var curIndex = this.stack.length - 1; + while (curIndex > 0 && types.indexOf(this.stack[curIndex].type) === -1) { + curIndex--; + } + return this.stack[curIndex]; + }, + firstParent: function (types) { + var curIndex = this.stack.length - 2; + while (curIndex > 0 && types.indexOf(this.stack[curIndex].type) === -1) { + curIndex--; + } + return this.stack[curIndex]; + }, + popUntil: function (types) { + while (types.indexOf(this.top().type) === -1 && !this.isRootTop()) { + this.stack.pop(); + } + return this.top(); + }, + addTo: function (types, type) { + var cur = this.popUntil(types); + ensureChildren(cur).children.push(type); + }, + addToAndPush: function (types, type) { + this.addTo(types, type); + this.stack.push(type); + }, + push: function (type) { + this.stack.push(type); + }, + topLastChild: function () { + return last(this.top().children); + }, + replaceTopLastChild: function (type) { + var children = ensureChildren(this.top()).children; + children.pop(); + children.push(type); + return type; + }, + replaceTopLastChildAndPush: function (type) { + this.replaceTopLastChild(type); + this.stack.push(type); + }, + replaceTopAndPush: function (type) { + var children; + if (this.top() === this.root) { + children = ensureChildren(this.top()).children; + } else { + this.stack.pop(); + children = ensureChildren(this.top()).children; + } + children.pop(); + children.push(type); + this.stack.push(type); + return type; + } + }); + var convertKeyToLookup = function (key) { + var lastPath = key.lastIndexOf('./'); + var lastDot = key.lastIndexOf('.'); + if (lastDot > lastPath) { + return key.substr(0, lastDot) + '@' + key.substr(lastDot + 1); + } + var firstNonPathCharIndex = lastPath === -1 ? 0 : lastPath + 2; + var firstNonPathChar = key.charAt(firstNonPathCharIndex); + if (firstNonPathChar === '.' || firstNonPathChar === '@') { + return key.substr(0, firstNonPathCharIndex) + '@' + key.substr(firstNonPathCharIndex + 1); + } else { + return key.substr(0, firstNonPathCharIndex) + '@' + key.substr(firstNonPathCharIndex); + } + }; + var convertToAtLookup = function (ast) { + if (ast.type === 'Lookup') { + canReflect.setKeyValue(ast, sourceTextSymbol, ast.key); + ast.key = convertKeyToLookup(ast.key); + } + return ast; + }; + var convertToHelperIfTopIsLookup = function (stack) { + var top = stack.top(); + if (top && top.type === 'Lookup') { + var base = stack.stack[stack.stack.length - 2]; + if (base.type !== 'Helper' && base) { + stack.replaceTopAndPush({ + type: 'Helper', + method: top + }); + } + } + }; + var expression = { + toComputeOrValue: expressionHelpers.toComputeOrValue, + convertKeyToLookup: convertKeyToLookup, + Literal: Literal, + Lookup: Lookup, + Arg: Arg, + Hash: Hash, + Hashes: Hashes, + Call: Call, + Helper: Helper, + Bracket: Bracket, + SetIdentifier: SetIdentifier, + tokenize: function (expression) { + var tokens = []; + (expression.trim() + ' ').replace(tokensRegExp, function (whole, arg) { + if (bracketSpaceRegExp.test(arg)) { + tokens.push(arg[0]); + tokens.push(arg.slice(1)); + } else { + tokens.push(arg); + } + }); + return tokens; + }, + lookupRules: { + 'default': function (ast, methodType, isArg) { + return ast.type === 'Helper' ? Helper : Lookup; + }, + 'method': function (ast, methodType, isArg) { + return Lookup; + } + }, + methodRules: { + 'default': function (ast) { + return ast.type === 'Call' ? Call : Helper; + }, + 'call': function (ast) { + return Call; + } + }, + parse: function (expressionString, options) { + options = options || {}; + var ast = this.ast(expressionString); + if (!options.lookupRule) { + options.lookupRule = 'default'; + } + if (typeof options.lookupRule === 'string') { + options.lookupRule = expression.lookupRules[options.lookupRule]; + } + if (!options.methodRule) { + options.methodRule = 'default'; + } + if (typeof options.methodRule === 'string') { + options.methodRule = expression.methodRules[options.methodRule]; + } + var expr = this.hydrateAst(ast, options, options.baseMethodType || 'Helper'); + return expr; + }, + hydrateAst: function (ast, options, methodType, isArg) { + var hashes; + if (ast.type === 'Lookup') { + var LookupRule = options.lookupRule(ast, methodType, isArg); + var lookup = new LookupRule(ast.key, ast.root && this.hydrateAst(ast.root, options, methodType), ast[sourceTextSymbol]); + return lookup; + } else if (ast.type === 'Literal') { + return new Literal(ast.value); + } else if (ast.type === 'Arg') { + return new Arg(this.hydrateAst(ast.children[0], options, methodType, isArg), { compute: true }); + } else if (ast.type === 'Hash') { + throw new Error(''); + } else if (ast.type === 'Hashes') { + hashes = {}; + ast.children.forEach(function (hash) { + hashes[hash.prop] = this.hydrateAst(hash.children[0], options, methodType, true); + }, this); + return new Hashes(hashes); + } else if (ast.type === 'Call' || ast.type === 'Helper') { + hashes = {}; + var args = [], children = ast.children, ExpressionType = options.methodRule(ast); + if (children) { + for (var i = 0; i < children.length; i++) { + var child = children[i]; + if (child.type === 'Hashes' && ast.type === 'Helper' && ExpressionType !== Call) { + child.children.forEach(function (hash) { + hashes[hash.prop] = this.hydrateAst(hash.children[0], options, ast.type, true); + }, this); + } else { + args.push(this.hydrateAst(child, options, ast.type, true)); + } + } + } + return new ExpressionType(this.hydrateAst(ast.method, options, ast.type), args, hashes); + } else if (ast.type === 'Bracket') { + var originalKey; + return new Bracket(this.hydrateAst(ast.children[0], options), ast.root ? this.hydrateAst(ast.root, options) : undefined, originalKey); + } + }, + ast: function (expression) { + var tokens = this.tokenize(expression); + return this.parseAst(tokens, { index: 0 }); + }, + parseAst: function (tokens, cursor) { + var stack = new Stack(), top, firstParent, lastToken; + while (cursor.index < tokens.length) { + var token = tokens[cursor.index], nextToken = tokens[cursor.index + 1]; + cursor.index++; + if (nextToken === '=') { + top = stack.top(); + if (top && top.type === 'Lookup') { + firstParent = stack.firstParent([ + 'Call', + 'Helper', + 'Hash' + ]); + if (firstParent.type === 'Call' || firstParent.type === 'Root') { + stack.popUntil(['Call']); + top = stack.top(); + stack.replaceTopAndPush({ + type: 'Helper', + method: top.type === 'Root' ? last(top.children) : top + }); + } + } + firstParent = stack.first([ + 'Call', + 'Helper', + 'Hashes', + 'Root' + ]); + var hash = { + type: 'Hash', + prop: token + }; + if (firstParent.type === 'Hashes') { + stack.addToAndPush(['Hashes'], hash); + } else { + stack.addToAndPush([ + 'Helper', + 'Call', + 'Root' + ], { + type: 'Hashes', + children: [hash] + }); + stack.push(hash); + } + cursor.index++; + } else if (literalRegExp.test(token)) { + convertToHelperIfTopIsLookup(stack); + firstParent = stack.first([ + 'Helper', + 'Call', + 'Hash', + 'Bracket' + ]); + if (firstParent.type === 'Hash' && (firstParent.children && firstParent.children.length > 0)) { + stack.addTo([ + 'Helper', + 'Call', + 'Bracket' + ], { + type: 'Literal', + value: utils.jsonParse(token) + }); + } else if (firstParent.type === 'Bracket' && (firstParent.children && firstParent.children.length > 0)) { + stack.addTo([ + 'Helper', + 'Call', + 'Hash' + ], { + type: 'Literal', + value: utils.jsonParse(token) + }); + } else { + stack.addTo([ + 'Helper', + 'Call', + 'Hash', + 'Bracket' + ], { + type: 'Literal', + value: utils.jsonParse(token) + }); + } + } else if (keyRegExp.test(token)) { + lastToken = stack.topLastChild(); + firstParent = stack.first([ + 'Helper', + 'Call', + 'Hash', + 'Bracket' + ]); + if (lastToken && (lastToken.type === 'Call' || lastToken.type === 'Bracket') && isAddingToExpression(token)) { + stack.replaceTopLastChildAndPush({ + type: 'Lookup', + root: lastToken, + key: token.slice(1) + }); + } else if (firstParent.type === 'Bracket') { + if (!(firstParent.children && firstParent.children.length > 0)) { + stack.addToAndPush(['Bracket'], { + type: 'Lookup', + key: token + }); + } else { + if (stack.first([ + 'Helper', + 'Call', + 'Hash', + 'Arg' + ]).type === 'Helper' && token[0] !== '.') { + stack.addToAndPush(['Helper'], { + type: 'Lookup', + key: token + }); + } else { + stack.replaceTopAndPush({ + type: 'Lookup', + key: token.slice(1), + root: firstParent + }); + } + } + } else { + convertToHelperIfTopIsLookup(stack); + stack.addToAndPush([ + 'Helper', + 'Call', + 'Hash', + 'Arg', + 'Bracket' + ], { + type: 'Lookup', + key: token + }); + } + } else if (token === '~') { + convertToHelperIfTopIsLookup(stack); + stack.addToAndPush([ + 'Helper', + 'Call', + 'Hash' + ], { + type: 'Arg', + key: token + }); + } else if (token === '(') { + top = stack.top(); + if (top.type === 'Lookup') { + stack.replaceTopAndPush({ + type: 'Call', + method: convertToAtLookup(top) + }); + } else { + throw new Error('Unable to understand expression ' + tokens.join('')); + } + } else if (token === ')') { + stack.popTo(['Call']); + } else if (token === ',') { + var call = stack.first(['Call']); + if (call.type !== 'Call') { + stack.popUntil(['Hash']); + } else { + stack.popUntil(['Call']); + } + } else if (token === '[') { + top = stack.top(); + lastToken = stack.topLastChild(); + if (lastToken && (lastToken.type === 'Call' || lastToken.type === 'Bracket')) { + stack.replaceTopLastChildAndPush({ + type: 'Bracket', + root: lastToken + }); + } else if (top.type === 'Lookup' || top.type === 'Bracket') { + var bracket = { + type: 'Bracket', + root: top + }; + stack.replaceTopAndPush(bracket); + } else if (top.type === 'Call') { + stack.addToAndPush(['Call'], { type: 'Bracket' }); + } else if (top === ' ') { + stack.popUntil([ + 'Lookup', + 'Call' + ]); + convertToHelperIfTopIsLookup(stack); + stack.addToAndPush([ + 'Helper', + 'Call', + 'Hash' + ], { type: 'Bracket' }); + } else { + stack.replaceTopAndPush({ type: 'Bracket' }); + } + } else if (token === ']') { + stack.pop(); + } else if (token === ' ') { + stack.push(token); + } + } + return stack.root.children[0]; + } + }; + module.exports = expression; +}); +/*can-stache@4.15.9#src/mustache_core*/ +define('can-stache@4.15.9#src/mustache_core', [ + 'require', + 'exports', + 'module', + 'can-view-live', + 'can-view-nodelist', + 'can-observation', + 'can-observation-recorder', + './utils', + './expression', + 'can-fragment', + 'can-dom-mutate', + 'can-symbol', + 'can-reflect', + 'can-log/dev/dev', + 'can-globals/document/document', + 'can-define-lazy-value' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var live = require('can-view-live'); + var nodeLists = require('can-view-nodelist'); + var Observation = require('can-observation'); + var ObservationRecorder = require('can-observation-recorder'); + var utils = require('./utils'); + var expression = require('./expression'); + var frag = require('can-fragment'); + var domMutate = require('can-dom-mutate'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + var dev = require('can-log/dev/dev'); + var getDocument = require('can-globals/document/document'); + var defineLazyValue = require('can-define-lazy-value'); + var toDOMSymbol = canSymbol.for('can.toDOM'); + function HelperOptions(scope, nodeList, exprData, stringOnly) { + this.metadata = { rendered: false }; + this.stringOnly = stringOnly; + this.scope = scope; + this.nodeList = nodeList; + this.exprData = exprData; + } + defineLazyValue(HelperOptions.prototype, 'context', function () { + return this.scope.peek('this'); + }); + var mustacheLineBreakRegExp = /(?:(^|\r?\n)(\s*)(\{\{([\s\S]*)\}\}\}?)([^\S\n\r]*)($|\r?\n))|(\{\{([\s\S]*)\}\}\}?)/g, mustacheWhitespaceRegExp = /(\s*)(\{\{\{?)(-?)([\s\S]*?)(-?)(\}\}\}?)(\s*)/g, k = function () { + }; + var viewInsertSymbol = canSymbol.for('can.viewInsert'); + function valueShouldBeInsertedAsHTML(value) { + return value !== null && typeof value === 'object' && (typeof value[toDOMSymbol] === 'function' || typeof value[viewInsertSymbol] === 'function' || typeof value.nodeType === 'number'); + } + var core = { + expression: expression, + makeEvaluator: function (scope, nodeList, mode, exprData, truthyRenderer, falseyRenderer, stringOnly) { + if (mode === '^') { + var temp = truthyRenderer; + truthyRenderer = falseyRenderer; + falseyRenderer = temp; + } + var value, helperOptions = new HelperOptions(scope, nodeList, exprData, stringOnly); + utils.createRenderers(helperOptions, scope, nodeList, truthyRenderer, falseyRenderer, stringOnly); + if (exprData instanceof expression.Call) { + value = exprData.value(scope, helperOptions); + } else if (exprData instanceof expression.Bracket) { + value = exprData.value(scope); + } else if (exprData instanceof expression.Lookup) { + value = exprData.value(scope); + } else if (exprData instanceof expression.Helper && exprData.methodExpr instanceof expression.Bracket) { + value = exprData.methodExpr.value(scope, helperOptions); + } else { + value = exprData.value(scope, helperOptions); + if (typeof value === 'function') { + return value; + } + } + if (!mode || helperOptions.metadata.rendered) { + return value; + } else if (mode === '#' || mode === '^') { + return function () { + var finalValue = canReflect.getValue(value); + var result; + if (helperOptions.metadata.rendered) { + result = finalValue; + } else if (typeof finalValue !== 'string' && canReflect.isListLike(finalValue)) { + var isObserveList = canReflect.isObservableLike(finalValue) && canReflect.isListLike(finalValue); + if (canReflect.getKeyValue(finalValue, 'length')) { + if (stringOnly) { + result = utils.getItemsStringContent(finalValue, isObserveList, helperOptions); + } else { + result = frag(utils.getItemsFragContent(finalValue, helperOptions, scope)); + } + } else { + result = helperOptions.inverse(scope); + } + } else { + result = finalValue ? helperOptions.fn(finalValue || scope) : helperOptions.inverse(scope); + } + helperOptions.metadata.rendered = false; + return result; + }; + } else { + } + }, + makeLiveBindingPartialRenderer: function (expressionString, state) { + expressionString = expressionString.trim(); + var exprData, partialName = expressionString.split(/\s+/).shift(); + if (partialName !== expressionString) { + exprData = core.expression.parse(expressionString); + } + return function (scope, parentSectionNodeList) { + var nodeList = [this]; + nodeList.expression = '>' + partialName; + nodeLists.register(nodeList, null, parentSectionNodeList || true, state.directlyNested); + var partialFrag = new Observation(function () { + var localPartialName = partialName; + if (exprData && exprData.argExprs.length === 1) { + var newContext = canReflect.getValue(exprData.argExprs[0].value(scope)); + if (typeof newContext === 'undefined') { + } else { + scope = scope.add(newContext); + } + } + var partial = canReflect.getKeyValue(scope.templateContext.partials, localPartialName); + var renderer; + if (partial) { + renderer = function () { + return partial.render ? partial.render(scope, nodeList) : partial(scope); + }; + } else { + var scopePartialName = scope.read(localPartialName, { isArgument: true }).value; + if (scopePartialName === null || !scopePartialName && localPartialName[0] === '*') { + return frag(''); + } + if (scopePartialName) { + localPartialName = scopePartialName; + } + renderer = function () { + if (typeof localPartialName === 'function') { + return localPartialName(scope, {}, nodeList); + } else { + var domRenderer = core.getTemplateById(localPartialName); + return domRenderer ? domRenderer(scope, {}, nodeList) : getDocument().createDocumentFragment(); + } + }; + } + var res = ObservationRecorder.ignore(renderer)(); + return frag(res); + }); + canReflect.setPriority(partialFrag, nodeList.nesting); + live.html(this, partialFrag, this.parentNode, nodeList); + }; + }, + makeStringBranchRenderer: function (mode, expressionString, state) { + var exprData = core.expression.parse(expressionString), fullExpression = mode + expressionString; + var branchRenderer = function branchRenderer(scope, truthyRenderer, falseyRenderer) { + var evaluator = scope.__cache[fullExpression]; + if (mode || !evaluator) { + evaluator = makeEvaluator(scope, null, mode, exprData, truthyRenderer, falseyRenderer, true); + if (!mode) { + scope.__cache[fullExpression] = evaluator; + } + } + var gotObservableValue = evaluator[canSymbol.for('can.onValue')], res; + if (gotObservableValue) { + res = canReflect.getValue(evaluator); + } else { + res = evaluator(); + } + return res == null ? '' : '' + res; + }; + branchRenderer.exprData = exprData; + return branchRenderer; + }, + makeLiveBindingBranchRenderer: function (mode, expressionString, state) { + var exprData = core.expression.parse(expressionString); + if (!(exprData instanceof expression.Helper) && !(exprData instanceof expression.Call) && !(exprData instanceof expression.Bracket) && !(exprData instanceof expression.Lookup)) { + exprData = new expression.Helper(exprData, [], {}); + } + var branchRenderer = function branchRenderer(scope, parentSectionNodeList, truthyRenderer, falseyRenderer) { + var stringOnly = state.tag; + var nodeList = [this]; + nodeList.expression = expressionString; + nodeLists.register(nodeList, null, parentSectionNodeList || true, state.directlyNested); + var evaluator = makeEvaluator(scope, nodeList, mode, exprData, truthyRenderer, falseyRenderer, stringOnly); + var gotObservableValue = evaluator[canSymbol.for('can.onValue')]; + var observable; + if (gotObservableValue) { + observable = evaluator; + } else { + observable = new Observation(evaluator, null, { isObservable: false }); + } + if (canReflect.setPriority(observable, nodeList.nesting) === false) { + throw new Error('can-stache unable to set priority on observable'); + } + canReflect.onValue(observable, k); + var value = canReflect.getValue(observable); + if (typeof value === 'function' && !(exprData instanceof expression.Lookup)) { + ObservationRecorder.ignore(value)(this); + } else if (canReflect.valueHasDependencies(observable)) { + if (state.attr) { + live.attr(this, state.attr, observable); + } else if (state.tag) { + live.attrs(this, observable); + } else if (state.text && !valueShouldBeInsertedAsHTML(value)) { + live.text(this, observable, this.parentNode, nodeList); + } else { + live.html(this, observable, this.parentNode, { nodeList: nodeList }); + } + } else { + if (state.attr) { + domMutate.setAttribute(this, state.attr, value); + } else if (state.tag) { + live.attrs(this, value); + } else if (state.text && !valueShouldBeInsertedAsHTML(value)) { + this.nodeValue = live.makeString(value); + } else if (value != null) { + if (typeof value[viewInsertSymbol] === 'function') { + var insert = value[viewInsertSymbol]({ nodeList: nodeList }); + var oldNodes = nodeLists.update(nodeList, [insert]); + nodeLists.replace(oldNodes, insert); + } else { + nodeLists.replace([this], frag(value, this.ownerDocument)); + } + } + } + canReflect.offValue(observable, k); + }; + branchRenderer.exprData = exprData; + return branchRenderer; + }, + splitModeFromExpression: function (expression, state) { + expression = expression.trim(); + var mode = expression.charAt(0); + if ('#/{&^>!<'.indexOf(mode) >= 0) { + expression = expression.substr(1).trim(); + } else { + mode = null; + } + if (mode === '{' && state.node) { + mode = null; + } + return { + mode: mode, + expression: expression + }; + }, + cleanLineEndings: function (template) { + return template.replace(mustacheLineBreakRegExp, function (whole, returnBefore, spaceBefore, special, expression, spaceAfter, returnAfter, spaceLessSpecial, spaceLessExpression, matchIndex) { + spaceAfter = spaceAfter || ''; + returnBefore = returnBefore || ''; + spaceBefore = spaceBefore || ''; + var modeAndExpression = splitModeFromExpression(expression || spaceLessExpression, {}); + if (spaceLessSpecial || '>{'.indexOf(modeAndExpression.mode) >= 0) { + return whole; + } else if ('^#!/'.indexOf(modeAndExpression.mode) >= 0) { + spaceBefore = returnBefore + spaceBefore && ' '; + return spaceBefore + special + (matchIndex !== 0 && returnAfter.length ? returnBefore + '\n' : ''); + } else { + return spaceBefore + special + spaceAfter + (spaceBefore.length || matchIndex !== 0 ? returnBefore + '\n' : ''); + } + }); + }, + cleanWhitespaceControl: function (template) { + return template.replace(mustacheWhitespaceRegExp, function (whole, spaceBefore, bracketBefore, controlBefore, expression, controlAfter, bracketAfter, spaceAfter, matchIndex) { + if (controlBefore === '-') { + spaceBefore = ''; + } + if (controlAfter === '-') { + spaceAfter = ''; + } + return spaceBefore + bracketBefore + expression + bracketAfter + spaceAfter; + }); + }, + getTemplateById: function () { + } + }; + var makeEvaluator = core.makeEvaluator, splitModeFromExpression = core.splitModeFromExpression; + module.exports = core; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-globals@1.2.0#base-url/base-url*/ +define('can-globals@1.2.0#base-url/base-url', [ + 'require', + 'exports', + 'module', + '../can-globals-instance', + '../global/global', + '../document/document' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var globals = require('../can-globals-instance'); + require('../global/global'); + require('../document/document'); + globals.define('base-url', function () { + var global = globals.getKeyValue('global'); + var domDocument = globals.getKeyValue('document'); + if (domDocument && 'baseURI' in domDocument) { + return domDocument.baseURI; + } else if (global.location) { + var href = global.location.href; + var lastSlash = href.lastIndexOf('/'); + return lastSlash !== -1 ? href.substr(0, lastSlash) : href; + } else if (typeof process !== 'undefined') { + return process.cwd(); + } + }); + module.exports = globals.makeExport('base-url'); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-parse-uri@1.2.0#can-parse-uri*/ +define('can-parse-uri@1.2.0#can-parse-uri', [ + 'require', + 'exports', + 'module', + 'can-namespace' +], function (require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + module.exports = namespace.parseURI = function (url) { + var m = String(url).replace(/^\s+|\s+$/g, '').match(/^([^:\/?#]+:)?(\/\/(?:[^:@]*(?::[^:@]*)?@)?(([^:\/?#]*)(?::(\d*))?))?([^?#]*)(\?[^#]*)?(#[\s\S]*)?/); + return m ? { + href: m[0] || '', + protocol: m[1] || '', + authority: m[2] || '', + host: m[3] || '', + hostname: m[4] || '', + port: m[5] || '', + pathname: m[6] || '', + search: m[7] || '', + hash: m[8] || '' + } : null; + }; +}); +/*can-join-uris@1.2.0#can-join-uris*/ +define('can-join-uris@1.2.0#can-join-uris', [ + 'require', + 'exports', + 'module', + 'can-namespace', + 'can-parse-uri' +], function (require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + var parseURI = require('can-parse-uri'); + module.exports = namespace.joinURIs = function (base, href) { + function removeDotSegments(input) { + var output = []; + input.replace(/^(\.\.?(\/|$))+/, '').replace(/\/(\.(\/|$))+/g, '/').replace(/\/\.\.$/, '/../').replace(/\/?[^\/]*/g, function (p) { + if (p === '/..') { + output.pop(); + } else { + output.push(p); + } + }); + return output.join('').replace(/^\//, input.charAt(0) === '/' ? '/' : ''); + } + href = parseURI(href || ''); + base = parseURI(base || ''); + return !href || !base ? null : (href.protocol || base.protocol) + (href.protocol || href.authority ? href.authority : base.authority) + removeDotSegments(href.protocol || href.authority || href.pathname.charAt(0) === '/' ? href.pathname : href.pathname ? (base.authority && !base.pathname ? '/' : '') + base.pathname.slice(0, base.pathname.lastIndexOf('/') + 1) + href.pathname : base.pathname) + (href.protocol || href.authority || href.pathname ? href.search : href.search || base.search) + href.hash; + }; +}); +/*can-stache@4.15.9#helpers/-debugger*/ +define('can-stache@4.15.9#helpers/-debugger', [ + 'require', + 'exports', + 'module', + 'can-log' +], function (require, exports, module) { + 'use strict'; + var canLog = require('can-log'); + function noop() { + } + var resolveValue = noop; + var evaluateArgs = noop; + var __testing = {}; + function debuggerHelper(left, right) { + canLog.warn('Forgotten {{debugger}} helper'); + } + debuggerHelper.requiresOptionsArgument = true; + module.exports = { + helper: debuggerHelper, + evaluateArgs: evaluateArgs, + resolveValue: resolveValue, + __testing: __testing + }; +}); +/*can-stache@4.15.9#src/truthy-observable*/ +define('can-stache@4.15.9#src/truthy-observable', [ + 'require', + 'exports', + 'module', + 'can-observation', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var Observation = require('can-observation'); + var canReflect = require('can-reflect'); + module.exports = function (observable) { + return new Observation(function truthyObservation() { + var val = canReflect.getValue(observable); + return !!val; + }); + }; +}); +/*can-dom-data@1.0.1#can-dom-data*/ +define('can-dom-data@1.0.1#can-dom-data', [ + 'require', + 'exports', + 'module', + 'can-namespace' +], function (require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + var isEmptyObject = function (obj) { + for (var prop in obj) { + return false; + } + return true; + }; + var data = new WeakMap(); + var deleteNode = function (node) { + var nodeDeleted = false; + if (data.has(node)) { + nodeDeleted = true; + data.delete(node); + } + return nodeDeleted; + }; + var setData = function (node, name, value) { + var store = data.get(node); + if (store === undefined) { + store = {}; + data.set(node, store); + } + if (name !== undefined) { + store[name] = value; + } + return store; + }; + var domData = { + _data: data, + get: function (node, key) { + var store = data.get(node); + return key === undefined ? store : store && store[key]; + }, + set: setData, + clean: function (node, prop) { + var itemData = data.get(node); + if (itemData && itemData[prop]) { + delete itemData[prop]; + } + if (isEmptyObject(itemData)) { + deleteNode(node); + } + }, + delete: deleteNode + }; + if (namespace.domData) { + throw new Error('You can\'t have two versions of can-dom-data, check your dependencies'); + } else { + module.exports = namespace.domData = domData; + } +}); +/*can-stache@4.15.9#helpers/-for-of*/ +define('can-stache@4.15.9#helpers/-for-of', [ + 'require', + 'exports', + 'module', + 'can-stache-helpers', + 'can-reflect', + 'can-observation', + 'can-view-live', + 'can-view-nodelist', + '../src/expression', + '../src/key-observable' +], function (require, exports, module) { + var helpers = require('can-stache-helpers'); + var canReflect = require('can-reflect'); + var Observation = require('can-observation'); + var live = require('can-view-live'); + var nodeLists = require('can-view-nodelist'); + var expression = require('../src/expression'); + var KeyObservable = require('../src/key-observable'); + var bindAndRead = function (value) { + if (value && canReflect.isValueLike(value)) { + Observation.temporarilyBind(value); + return canReflect.getValue(value); + } else { + return value; + } + }; + function forOfObject(object, variableName, options) { + var result = []; + canReflect.each(object, function (val, key) { + var value = new KeyObservable(object, key); + var variableScope = {}; + if (variableName !== undefined) { + variableScope[variableName] = value; + } + result.push(options.fn(options.scope.add({ key: key }, { special: true }).addLetContext(variableScope))); + }); + return options.stringOnly ? result.join('') : result; + } + var forHelper = function (helperOptions) { + if (helperOptions.exprData.argExprs.length !== 1) { + throw new Error('for(of) broken syntax'); + } + var helperExpr = helperOptions.exprData.argExprs[0].expr; + var variableName, valueLookup, valueObservable; + if (helperExpr instanceof expression.Lookup) { + valueObservable = helperExpr.value(helperOptions.scope); + } else if (helperExpr instanceof expression.Helper) { + var inLookup = helperExpr.argExprs[0]; + if (inLookup.key !== 'of') { + throw new Error('for(of) broken syntax'); + } + variableName = helperExpr.methodExpr.key; + valueLookup = helperExpr.argExprs[1]; + valueObservable = valueLookup.value(helperOptions.scope); + } + var items = valueObservable; + var args = [].slice.call(arguments), options = args.pop(), resolved = bindAndRead(items); + if (resolved && !canReflect.isListLike(resolved)) { + return forOfObject(resolved, variableName, helperOptions); + } + if (options.stringOnly) { + var parts = []; + canReflect.eachIndex(resolved, function (value, index) { + var variableScope = {}; + if (variableName !== undefined) { + variableScope[variableName] = value; + } + parts.push(helperOptions.fn(options.scope.add({ index: index }, { special: true }).addLetContext(variableScope))); + }); + return parts.join(''); + } else { + options.metadata.rendered = true; + return function (el) { + var nodeList = [el]; + nodeList.expression = 'live.list'; + nodeLists.register(nodeList, null, options.nodeList, true); + nodeLists.update(options.nodeList, [el]); + var cb = function (item, index, parentNodeList) { + var variableScope = {}; + if (variableName !== undefined) { + variableScope[variableName] = item; + } + return options.fn(options.scope.add({ index: index }, { special: true }).addLetContext(variableScope), options.options, parentNodeList); + }; + live.list(el, items, cb, options.context, el.parentNode, nodeList, function (list, parentNodeList) { + return options.inverse(options.scope, options.options, parentNodeList); + }); + }; + } + }; + forHelper.isLiveBound = true; + forHelper.requiresOptionsArgument = true; + forHelper.ignoreArgLookup = function ignoreArgLookup(index) { + return index === 0; + }; + helpers.for = forHelper; +}); +/*can-stache@4.15.9#helpers/-let*/ +define('can-stache@4.15.9#helpers/-let', [ + 'require', + 'exports', + 'module', + 'can-stache-helpers', + 'can-reflect' +], function (require, exports, module) { + var helpers = require('can-stache-helpers'); + var canReflect = require('can-reflect'); + function isVariable(scope) { + return scope._meta.variable === true; + } + helpers['let'] = function (options) { + var variableScope = options.scope.getScope(isVariable); + if (!variableScope) { + throw new Error('There is no variable scope!'); + } + canReflect.assignMap(variableScope._context, options.hash); + return document.createTextNode(''); + }; +}); +/*can-stache@4.15.9#helpers/core*/ +define('can-stache@4.15.9#helpers/core', [ + 'require', + 'exports', + 'module', + 'can-view-live', + 'can-view-nodelist', + '../src/utils', + 'can-globals/base-url/base-url', + 'can-join-uris', + 'can-assign', + 'can-log/dev/dev', + 'can-reflect', + './-debugger', + '../src/key-observable', + 'can-observation', + '../src/truthy-observable', + 'can-stache-helpers', + 'can-dom-data', + 'can-dom-data-state', + './-for-of', + './-let' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var live = require('can-view-live'); + var nodeLists = require('can-view-nodelist'); + var utils = require('../src/utils'); + var getBaseURL = require('can-globals/base-url/base-url'); + var joinURIs = require('can-join-uris'); + var assign = require('can-assign'); + var dev = require('can-log/dev/dev'); + var canReflect = require('can-reflect'); + var debuggerHelper = require('./-debugger').helper; + var KeyObservable = require('../src/key-observable'); + var Observation = require('can-observation'); + var TruthyObservable = require('../src/truthy-observable'); + var helpers = require('can-stache-helpers'); + var domData = require('can-dom-data'); + var domDataState = require('can-dom-data-state'); + require('./-for-of'); + require('./-let'); + var builtInHelpers = {}; + var helpersCore = { + looksLikeOptions: function (options) { + return options && typeof options.fn === 'function' && typeof options.inverse === 'function'; + }, + resolve: function (value) { + if (value && canReflect.isValueLike(value)) { + return canReflect.getValue(value); + } else { + return value; + } + }, + resolveHash: function (hash) { + var params = {}; + for (var prop in hash) { + params[prop] = helpersCore.resolve(hash[prop]); + } + return params; + }, + bindAndRead: function (value) { + if (value && canReflect.isValueLike(value)) { + Observation.temporarilyBind(value); + return canReflect.getValue(value); + } else { + return value; + } + }, + registerHelper: function (name, callback) { + callback.requiresOptionsArgument = true; + helpers[name] = callback; + }, + registerHelpers: function (helpers) { + var name, callback; + for (name in helpers) { + callback = helpers[name]; + helpersCore.registerHelper(name, helpersCore.makeSimpleHelper(callback)); + } + }, + makeSimpleHelper: function (fn) { + return function () { + var realArgs = []; + canReflect.eachIndex(arguments, function (val) { + realArgs.push(helpersCore.resolve(val)); + }); + return fn.apply(this, realArgs); + }; + }, + addHelper: function (name, callback) { + if (typeof name === 'object') { + return helpersCore.registerHelpers(name); + } + return helpersCore.registerHelper(name, helpersCore.makeSimpleHelper(callback)); + }, + addLiveHelper: function (name, callback) { + callback.isLiveBound = true; + return helpersCore.registerHelper(name, callback); + }, + getHelper: function (name, scope) { + var helper = scope && scope.getHelper(name); + if (!helper) { + helper = helpers[name]; + } + return helper; + }, + __resetHelpers: function () { + for (var helper in helpers) { + delete helpers[helper]; + } + helpersCore.addBuiltInHelpers(); + }, + addBuiltInHelpers: function () { + canReflect.each(builtInHelpers, function (helper, helperName) { + helpers[helperName] = helper; + }); + }, + _makeLogicHelper: function (name, logic) { + var logicHelper = assign(function () { + var args = Array.prototype.slice.call(arguments, 0), options; + if (helpersCore.looksLikeOptions(args[args.length - 1])) { + options = args.pop(); + } + function callLogic() { + if (options) { + return logic(args) ? true : false; + } else { + return logic(args); + } + } + var callFn = new Observation(callLogic); + if (options) { + return callFn.get() ? options.fn() : options.inverse(); + } else { + return callFn.get(); + } + }, { + requiresOptionsArgument: true, + isLiveBound: true + }); + return logicHelper; + } + }; + var ifHelper = assign(function ifHelper(expr, options) { + var value; + if (expr && canReflect.isValueLike(expr)) { + value = canReflect.getValue(new TruthyObservable(expr)); + } else { + value = !!helpersCore.resolve(expr); + } + if (value) { + return options.fn(options.scope || this); + } else { + return options.inverse(options.scope || this); + } + }, { + requiresOptionsArgument: true, + isLiveBound: true + }); + var isHelper = helpersCore._makeLogicHelper('eq', function eqHelper(args) { + var curValue, lastValue; + for (var i = 0; i < args.length; i++) { + curValue = helpersCore.resolve(args[i]); + curValue = typeof curValue === 'function' ? curValue() : curValue; + if (i > 0) { + if (curValue !== lastValue) { + return false; + } + } + lastValue = curValue; + } + return true; + }); + var andHelper = helpersCore._makeLogicHelper('and', function andHelper(args) { + if (args.length === 0) { + return false; + } + var last; + for (var i = 0, len = args.length; i < len; i++) { + last = helpersCore.resolve(args[i]); + if (!last) { + return last; + } + } + return last; + }); + var orHelper = helpersCore._makeLogicHelper('or', function orHelper(args) { + if (args.length === 0) { + return false; + } + var last; + for (var i = 0, len = args.length; i < len; i++) { + last = helpersCore.resolve(args[i]); + if (last) { + return last; + } + } + return last; + }); + var switchHelper = function (expression, options) { + helpersCore.resolve(expression); + var found = false; + var caseHelper = function (value, options) { + if (!found && helpersCore.resolve(expression) === helpersCore.resolve(value)) { + found = true; + return options.fn(options.scope.peek('this') || this); + } + }; + caseHelper.requiresOptionsArgument = true; + var defaultHelper = function (options) { + if (!found) { + return options ? options.scope.peek('this') : true; + } + }; + defaultHelper.requiresOptionsArgument = true; + canReflect.assignSymbols(defaultHelper, { + 'can.isValueLike': true, + 'can.isFunctionLike': false, + 'can.getValue': function () { + return this(options); + } + }); + var newScope = options.scope.add({ + case: caseHelper, + default: defaultHelper + }, { notContext: true }); + return options.fn(newScope, options); + }; + switchHelper.requiresOptionsArgument = true; + var domDataHelper = function (attr, value) { + var data = (helpersCore.looksLikeOptions(value) ? value.context : value) || this; + return function setDomData(el) { + domData.set(el, attr, data); + }; + }; + var joinBaseHelper = function (firstExpr) { + var args = [].slice.call(arguments); + var options = args.pop(); + var moduleReference = args.map(function (expr) { + var value = helpersCore.resolve(expr); + return typeof value === 'function' ? value() : value; + }).join(''); + var templateModule = canReflect.getKeyValue(options.scope.templateContext.helpers, 'module'); + var parentAddress = templateModule ? templateModule.uri : undefined; + var isRelative = moduleReference[0] === '.'; + if (isRelative && parentAddress) { + return joinURIs(parentAddress, moduleReference); + } else { + var baseURL = typeof System !== 'undefined' && (System.renderingBaseURL || System.baseURL) || getBaseURL(); + if (moduleReference[0] !== '/' && baseURL[baseURL.length - 1] !== '/') { + baseURL += '/'; + } + return joinURIs(baseURL, moduleReference); + } + }; + joinBaseHelper.requiresOptionsArgument = true; + var eachHelper = function (items) { + var args = [].slice.call(arguments), options = args.pop(), hashExprs = options.exprData.hashExprs, resolved = helpersCore.bindAndRead(items), hashOptions, aliases; + if (canReflect.size(hashExprs) > 0) { + hashOptions = {}; + canReflect.eachKey(hashExprs, function (exprs, key) { + hashOptions[exprs.key] = key; + }); + } + if ((canReflect.isObservableLike(resolved) && canReflect.isListLike(resolved) || canReflect.isListLike(resolved) && canReflect.isValueLike(items)) && !options.stringOnly) { + options.metadata.rendered = true; + return function (el) { + var nodeList = [el]; + nodeList.expression = 'live.list'; + nodeLists.register(nodeList, null, options.nodeList, true); + nodeLists.update(options.nodeList, [el]); + var cb = function (item, index, parentNodeList) { + var aliases = {}; + if (canReflect.size(hashOptions) > 0) { + if (hashOptions.value) { + aliases[hashOptions.value] = item; + } + if (hashOptions.index) { + aliases[hashOptions.index] = index; + } + } + return options.fn(options.scope.add(aliases, { notContext: true }).add({ index: index }, { special: true }).add(item), options.options, parentNodeList); + }; + live.list(el, items, cb, options.context, el.parentNode, nodeList, function (list, parentNodeList) { + return options.inverse(options.scope.add(list), options.options, parentNodeList); + }); + }; + } + var expr = helpersCore.resolve(items), result; + if (!!expr && canReflect.isListLike(expr)) { + result = utils.getItemsFragContent(expr, options, options.scope); + return options.stringOnly ? result.join('') : result; + } else if (canReflect.isObservableLike(expr) && canReflect.isMapLike(expr) || expr instanceof Object) { + result = []; + canReflect.each(expr, function (val, key) { + var value = new KeyObservable(expr, key); + aliases = {}; + if (canReflect.size(hashOptions) > 0) { + if (hashOptions.value) { + aliases[hashOptions.value] = value; + } + if (hashOptions.key) { + aliases[hashOptions.key] = key; + } + } + result.push(options.fn(options.scope.add(aliases, { notContext: true }).add({ key: key }, { special: true }).add(value))); + }); + return options.stringOnly ? result.join('') : result; + } + }; + eachHelper.isLiveBound = true; + eachHelper.requiresOptionsArgument = true; + eachHelper.ignoreArgLookup = function ignoreArgLookup(index) { + return index === 1; + }; + var indexHelper = assign(function indexHelper(offset, options) { + if (!options) { + options = offset; + offset = 0; + } + var index = options.scope.peek('scope.index'); + return '' + ((typeof index === 'function' ? index() : index) + offset); + }, { requiresOptionsArgument: true }); + var withHelper = function (expr, options) { + var ctx = expr; + if (!options) { + options = expr; + expr = true; + ctx = options.hash; + } else { + expr = helpersCore.resolve(expr); + if (options.hash && canReflect.size(options.hash) > 0) { + ctx = options.scope.add(options.hash, { notContext: true }).add(ctx); + } + } + return options.fn(ctx || {}); + }; + withHelper.requiresOptionsArgument = true; + var dataHelper = function (attr, value) { + var data = (helpersCore.looksLikeOptions(value) ? value.context : value) || this; + return function setData(el) { + domDataState.set.call(el, attr, data); + }; + }; + var unlessHelper = function (expr, options) { + return ifHelper.apply(this, [ + expr, + assign(assign({}, options), { + fn: options.inverse, + inverse: options.fn + }) + ]); + }; + unlessHelper.requiresOptionsArgument = true; + unlessHelper.isLiveBound = true; + var builtInHelpers = { + 'debugger': debuggerHelper, + each: eachHelper, + eachOf: eachHelper, + index: indexHelper, + 'if': ifHelper, + is: isHelper, + eq: isHelper, + unless: unlessHelper, + 'with': withHelper, + console: console, + data: dataHelper, + domData: domDataHelper, + 'switch': switchHelper, + joinBase: joinBaseHelper, + and: andHelper, + or: orHelper + }; + helpersCore.addBuiltInHelpers(); + module.exports = helpersCore; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-stache@4.15.9#helpers/converter*/ +define('can-stache@4.15.9#helpers/converter', [ + 'require', + 'exports', + 'module', + './core', + '../src/set-identifier', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var helpers = require('./core'); + var SetIdentifier = require('../src/set-identifier'); + var canReflect = require('can-reflect'); + function makeConverter(getterSetter) { + getterSetter = getterSetter || {}; + return function (newVal, source) { + var args = canReflect.toArray(arguments); + if (newVal instanceof SetIdentifier) { + return typeof getterSetter.set === 'function' ? getterSetter.set.apply(this, [newVal.value].concat(args.slice(1))) : source(newVal.value); + } else { + return typeof getterSetter.get === 'function' ? getterSetter.get.apply(this, args) : args[0]; + } + }; + } + var converterPackages = new WeakMap(); + helpers.addConverter = function (name, getterSetter) { + if (typeof name === 'object') { + if (!converterPackages.has(name)) { + converterPackages.set(name, true); + canReflect.eachKey(name, function (getterSetter, name) { + helpers.addConverter(name, getterSetter); + }); + } + return; + } + var helper = makeConverter(getterSetter); + helper.isLiveBound = true; + helpers.registerHelper(name, helper); + }; + helpers.registerConverter = function (name, getterSetter) { + helpers.registerHelper(name, makeConverter(getterSetter)); + }; + var converterHelpers = { + 'not': { + get: function (obs, options) { + if (helpers.looksLikeOptions(options)) { + return canReflect.getValue(obs) ? options.inverse() : options.fn(); + } else { + return !canReflect.getValue(obs); + } + }, + set: function (newVal, obs) { + canReflect.setValue(obs, !newVal); + } + } + }; + helpers.addConverter(converterHelpers); + module.exports = helpers; +}); +/*can-stache-ast@1.1.0#controls*/ +define('can-stache-ast@1.1.0#controls', function (require, exports, module) { + 'use strict'; + var mustacheLineBreakRegExp = /(?:(^|\r?\n)(\s*)(\{\{([\s\S]*)\}\}\}?)([^\S\n\r]*)($|\r?\n))|(\{\{([\s\S]*)\}\}\}?)/g, mustacheWhitespaceRegExp = /(\s*)(\{\{\{?)(-?)([\s\S]*?)(-?)(\}\}\}?)(\s*)/g; + function splitModeFromExpression(expression, state) { + expression = expression.trim(); + var mode = expression.charAt(0); + if ('#/{&^>!<'.indexOf(mode) >= 0) { + expression = expression.substr(1).trim(); + } else { + mode = null; + } + if (mode === '{' && state.node) { + mode = null; + } + return { + mode: mode, + expression: expression + }; + } + function cleanLineEndings(template) { + return template.replace(mustacheLineBreakRegExp, function (whole, returnBefore, spaceBefore, special, expression, spaceAfter, returnAfter, spaceLessSpecial, spaceLessExpression, matchIndex) { + spaceAfter = spaceAfter || ''; + returnBefore = returnBefore || ''; + spaceBefore = spaceBefore || ''; + var modeAndExpression = splitModeFromExpression(expression || spaceLessExpression, {}); + if (spaceLessSpecial || '>{'.indexOf(modeAndExpression.mode) >= 0) { + return whole; + } else if ('^#!/'.indexOf(modeAndExpression.mode) >= 0) { + spaceBefore = returnBefore + spaceBefore && ' '; + return spaceBefore + special + (matchIndex !== 0 && returnAfter.length ? returnBefore + '\n' : ''); + } else { + return spaceBefore + special + spaceAfter + (spaceBefore.length || matchIndex !== 0 ? returnBefore + '\n' : ''); + } + }); + } + function whiteSpaceReplacement(whole, spaceBefore, bracketBefore, controlBefore, expression, controlAfter, bracketAfter, spaceAfter) { + if (controlBefore === '-') { + spaceBefore = ''; + } + if (controlAfter === '-') { + spaceAfter = ''; + } + return spaceBefore + bracketBefore + expression + bracketAfter + spaceAfter; + } + function cleanWhitespaceControl(template) { + return template.replace(mustacheWhitespaceRegExp, whiteSpaceReplacement); + } + exports.cleanLineEndings = cleanLineEndings; + exports.cleanWhitespaceControl = cleanWhitespaceControl; +}); +/*can-stache-ast@1.1.0#can-stache-ast*/ +define('can-stache-ast@1.1.0#can-stache-ast', [ + 'require', + 'exports', + 'module', + './controls', + 'can-view-parser' +], function (require, exports, module) { + 'use strict'; + var controls = require('./controls'); + var parser = require('can-view-parser'); + exports.parse = function (filename, source) { + if (arguments.length === 1) { + source = arguments[0]; + filename = undefined; + } + var template = source; + template = controls.cleanWhitespaceControl(template); + template = controls.cleanLineEndings(template); + var imports = [], dynamicImports = [], importDeclarations = [], ases = {}, attributes = new Map(), inImport = false, inFrom = false, inAs = false, isUnary = false, importIsDynamic = false, currentAs = '', currentFrom = '', currentAttrName = null; + function processImport(line) { + if (currentAs) { + ases[currentAs] = currentFrom; + currentAs = ''; + } + if (importIsDynamic) { + dynamicImports.push(currentFrom); + } else { + imports.push(currentFrom); + } + importDeclarations.push({ + specifier: currentFrom, + loc: { line: line }, + attributes: attributes + }); + attributes = new Map(); + } + var program = parser(template, { + filename: filename, + start: function (tagName, unary) { + if (tagName === 'can-import') { + isUnary = unary; + importIsDynamic = false; + inImport = true; + } else if (tagName === 'can-dynamic-import') { + isUnary = unary; + importIsDynamic = true; + inImport = true; + } else if (inImport) { + importIsDynamic = true; + inImport = false; + } + }, + attrStart: function (attrName) { + currentAttrName = attrName; + attributes.set(currentAttrName, true); + if (attrName === 'from') { + inFrom = true; + } else if (attrName === 'as' || attrName === 'export-as') { + inAs = true; + } + }, + attrEnd: function (attrName) { + if (attrName === 'from') { + inFrom = false; + } else if (attrName === 'as' || attrName === 'export-as') { + inAs = false; + } + }, + attrValue: function (value) { + if (inImport) { + attributes.set(currentAttrName, value); + } + if (inFrom && inImport) { + currentFrom = value; + } else if (inAs && inImport) { + currentAs = value; + } + }, + end: function (tagName, unary, line) { + if ((tagName === 'can-import' || tagName === 'can-dynamic-import') && isUnary) { + processImport(line); + } + }, + close: function (tagName, unary, line) { + if (tagName === 'can-import' || tagName === 'can-dynamic-import') { + processImport(line); + } + }, + chars: function (text) { + if (text.trim().length > 0) { + importIsDynamic = true; + } + }, + special: function () { + importIsDynamic = true; + } + }, true); + return { + intermediate: program, + program: program, + imports: imports, + dynamicImports: dynamicImports, + importDeclarations: importDeclarations, + ases: ases, + exports: ases + }; + }; +}); +/*can-import-module@1.2.0#can-import-module*/ +define('can-import-module@1.2.0#can-import-module', [ + 'require', + 'exports', + 'module', + 'can-globals/global/global', + 'can-namespace' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var getGlobal = require('can-globals/global/global'); + var namespace = require('can-namespace'); + module.exports = namespace.import = function (moduleName, parentName) { + return new Promise(function (resolve, reject) { + try { + var global = getGlobal(); + if (typeof global.System === 'object' && isFunction(global.System['import'])) { + global.System['import'](moduleName, { name: parentName }).then(resolve, reject); + } else if (global.define && global.define.amd) { + global.require([moduleName], function (value) { + resolve(value); + }); + } else if (global.require) { + resolve(global.require(moduleName)); + } else { + if (typeof stealRequire !== 'undefined') { + steal.import(moduleName, { name: parentName }).then(resolve, reject); + } else { + resolve(); + } + } + } catch (err) { + reject(err); + } + }); + }; + function isFunction(fn) { + return typeof fn === 'function'; + } + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-stache@4.15.9#can-stache*/ +define('can-stache@4.15.9#can-stache', [ + 'require', + 'exports', + 'module', + 'can-view-parser', + 'can-view-callbacks', + './src/html_section', + './src/text_section', + './src/mustache_core', + './helpers/core', + './helpers/converter', + 'can-stache-ast', + './src/utils', + 'can-attribute-encoder', + 'can-log/dev/dev', + 'can-namespace', + 'can-globals/document/document', + 'can-assign', + 'can-import-module', + 'can-reflect', + 'can-view-scope', + 'can-view-scope/template-context', + 'can-observation-recorder', + 'can-symbol', + 'can-view-target', + 'can-view-nodelist' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var parser = require('can-view-parser'); + var viewCallbacks = require('can-view-callbacks'); + var HTMLSectionBuilder = require('./src/html_section'); + var TextSectionBuilder = require('./src/text_section'); + var mustacheCore = require('./src/mustache_core'); + var mustacheHelpers = require('./helpers/core'); + require('./helpers/converter'); + var getIntermediateAndImports = require('can-stache-ast').parse; + var utils = require('./src/utils'); + var makeRendererConvertScopes = utils.makeRendererConvertScopes; + var last = utils.last; + var attributeEncoder = require('can-attribute-encoder'); + var dev = require('can-log/dev/dev'); + var namespace = require('can-namespace'); + var DOCUMENT = require('can-globals/document/document'); + var assign = require('can-assign'); + var importer = require('can-import-module'); + var canReflect = require('can-reflect'); + var Scope = require('can-view-scope'); + var TemplateContext = require('can-view-scope/template-context'); + var ObservationRecorder = require('can-observation-recorder'); + var canSymbol = require('can-symbol'); + require('can-view-target'); + require('can-view-nodelist'); + if (!viewCallbacks.tag('content')) { + viewCallbacks.tag('content', function (el, tagData) { + return tagData.scope; + }); + } + var isViewSymbol = canSymbol.for('can.isView'); + var wrappedAttrPattern = /[{(].*[)}]/; + var colonWrappedAttrPattern = /^on:|(:to|:from|:bind)$|.*:to:on:.*/; + var svgNamespace = 'http://www.w3.org/2000/svg', xmlnsAttrNamespaceURI = 'http://www.w3.org/2000/xmlns/', xlinkHrefAttrNamespaceURI = 'http://www.w3.org/1999/xlink'; + var namespaces = { + 'svg': svgNamespace, + 'g': svgNamespace, + 'defs': svgNamespace, + 'path': svgNamespace, + 'filter': svgNamespace, + 'feMorphology': svgNamespace, + 'feGaussianBlur': svgNamespace, + 'feOffset': svgNamespace, + 'feComposite': svgNamespace, + 'feColorMatrix': svgNamespace, + 'use': svgNamespace + }, attrsNamespacesURI = { + 'xmlns': xmlnsAttrNamespaceURI, + 'xlink:href': xlinkHrefAttrNamespaceURI + }, textContentOnlyTag = { + style: true, + script: true + }; + function stache(filename, template) { + if (arguments.length === 1) { + template = arguments[0]; + filename = undefined; + } + var inlinePartials = {}; + if (typeof template === 'string') { + template = mustacheCore.cleanWhitespaceControl(template); + template = mustacheCore.cleanLineEndings(template); + } + var section = new HTMLSectionBuilder(filename), state = { + node: null, + attr: null, + sectionElementStack: [], + text: false, + namespaceStack: [], + textContentOnly: null + }, makeRendererAndUpdateSection = function (section, mode, stache, lineNo) { + if (mode === '>') { + section.add(mustacheCore.makeLiveBindingPartialRenderer(stache, copyState({ + filename: section.filename, + lineNo: lineNo + }))); + } else if (mode === '/') { + var createdSection = section.last(); + if (createdSection.startedWith === '<') { + inlinePartials[stache] = section.endSubSectionAndReturnRenderer(); + section.removeCurrentNode(); + } else { + section.endSection(); + } + if (section instanceof HTMLSectionBuilder) { + state.sectionElementStack.pop(); + } + } else if (mode === 'else') { + section.inverse(); + } else { + var makeRenderer = section instanceof HTMLSectionBuilder ? mustacheCore.makeLiveBindingBranchRenderer : mustacheCore.makeStringBranchRenderer; + if (mode === '{' || mode === '&') { + section.add(makeRenderer(null, stache, copyState({ + filename: section.filename, + lineNo: lineNo + }))); + } else if (mode === '#' || mode === '^' || mode === '<') { + var renderer = makeRenderer(mode, stache, copyState({ + filename: section.filename, + lineNo: lineNo + })); + var sectionItem = { type: 'section' }; + section.startSection(renderer); + section.last().startedWith = mode; + if (section instanceof HTMLSectionBuilder) { + state.sectionElementStack.push(sectionItem); + } + } else { + section.add(makeRenderer(null, stache, copyState({ + text: true, + filename: section.filename, + lineNo: lineNo + }))); + } + } + }, isDirectlyNested = function () { + var lastElement = state.sectionElementStack[state.sectionElementStack.length - 1]; + return state.sectionElementStack.length ? lastElement.type === 'section' || lastElement.type === 'custom' : true; + }, copyState = function (overwrites) { + var cur = { + tag: state.node && state.node.tag, + attr: state.attr && state.attr.name, + directlyNested: isDirectlyNested(), + textContentOnly: !!state.textContentOnly + }; + return overwrites ? assign(cur, overwrites) : cur; + }, addAttributesCallback = function (node, callback) { + if (!node.attributes) { + node.attributes = []; + } + node.attributes.unshift(callback); + }; + parser(template, { + filename: filename, + start: function (tagName, unary, lineNo) { + var matchedNamespace = namespaces[tagName]; + if (matchedNamespace && !unary) { + state.namespaceStack.push(matchedNamespace); + } + state.node = { + tag: tagName, + children: [], + namespace: matchedNamespace || last(state.namespaceStack) + }; + }, + end: function (tagName, unary, lineNo) { + var isCustomTag = viewCallbacks.tag(tagName); + var directlyNested = isDirectlyNested(); + if (unary) { + section.add(state.node); + if (isCustomTag) { + addAttributesCallback(state.node, function (scope, parentNodeList) { + viewCallbacks.tagHandler(this, tagName, { + scope: scope, + subtemplate: null, + templateType: 'stache', + parentNodeList: parentNodeList, + directlyNested: directlyNested + }); + }); + } + } else { + section.push(state.node); + state.sectionElementStack.push({ + type: isCustomTag ? 'custom' : null, + tag: isCustomTag ? null : tagName, + templates: {}, + directlyNested: directlyNested + }); + if (isCustomTag) { + section.startSubSection(); + } else if (textContentOnlyTag[tagName]) { + state.textContentOnly = new TextSectionBuilder(filename); + } + } + state.node = null; + }, + close: function (tagName, lineNo) { + var matchedNamespace = namespaces[tagName]; + if (matchedNamespace) { + state.namespaceStack.pop(); + } + var isCustomTag = viewCallbacks.tag(tagName), renderer; + if (isCustomTag) { + renderer = section.endSubSectionAndReturnRenderer(); + } + if (textContentOnlyTag[tagName]) { + section.last().add(state.textContentOnly.compile(copyState())); + state.textContentOnly = null; + } + var oldNode = section.pop(); + if (isCustomTag) { + if (tagName === 'can-template') { + var parent = state.sectionElementStack[state.sectionElementStack.length - 2]; + if (renderer) { + parent.templates[oldNode.attrs.name] = makeRendererConvertScopes(renderer); + } + section.removeCurrentNode(); + } else { + var current = state.sectionElementStack[state.sectionElementStack.length - 1]; + addAttributesCallback(oldNode, function (scope, parentNodeList) { + viewCallbacks.tagHandler(this, tagName, { + scope: scope, + subtemplate: renderer ? makeRendererConvertScopes(renderer) : renderer, + templateType: 'stache', + parentNodeList: parentNodeList, + templates: current.templates, + directlyNested: current.directlyNested + }); + }); + } + } + state.sectionElementStack.pop(); + }, + attrStart: function (attrName, lineNo) { + if (state.node.section) { + state.node.section.add(attrName + '="'); + } else { + state.attr = { + name: attrName, + value: '' + }; + } + }, + attrEnd: function (attrName, lineNo) { + var matchedAttrNamespacesURI = attrsNamespacesURI[attrName]; + if (state.node.section) { + state.node.section.add('" '); + } else { + if (!state.node.attrs) { + state.node.attrs = {}; + } + if (state.attr.section) { + state.node.attrs[state.attr.name] = state.attr.section.compile(copyState()); + } else if (matchedAttrNamespacesURI) { + state.node.attrs[state.attr.name] = { + value: state.attr.value, + namespaceURI: attrsNamespacesURI[attrName] + }; + } else { + state.node.attrs[state.attr.name] = state.attr.value; + } + var attrCallback = viewCallbacks.attr(attrName); + if (attrCallback) { + if (!state.node.attributes) { + state.node.attributes = []; + } + state.node.attributes.push(function (scope, nodeList) { + attrCallback(this, { + attributeName: attrName, + scope: scope, + nodeList: nodeList + }); + }); + } + state.attr = null; + } + }, + attrValue: function (value, lineNo) { + var section = state.node.section || state.attr.section; + if (section) { + section.add(value); + } else { + state.attr.value += value; + } + }, + chars: function (text, lineNo) { + (state.textContentOnly || section).add(text); + }, + special: function (text, lineNo) { + var firstAndText = mustacheCore.splitModeFromExpression(text, state), mode = firstAndText.mode, expression = firstAndText.expression; + if (expression === 'else') { + var inverseSection; + if (state.attr && state.attr.section) { + inverseSection = state.attr.section; + } else if (state.node && state.node.section) { + inverseSection = state.node.section; + } else { + inverseSection = state.textContentOnly || section; + } + inverseSection.inverse(); + return; + } + if (mode === '!') { + return; + } + if (state.node && state.node.section) { + makeRendererAndUpdateSection(state.node.section, mode, expression, lineNo); + if (state.node.section.subSectionDepth() === 0) { + state.node.attributes.push(state.node.section.compile(copyState())); + delete state.node.section; + } + } else if (state.attr) { + if (!state.attr.section) { + state.attr.section = new TextSectionBuilder(filename); + if (state.attr.value) { + state.attr.section.add(state.attr.value); + } + } + makeRendererAndUpdateSection(state.attr.section, mode, expression, lineNo); + } else if (state.node) { + if (!state.node.attributes) { + state.node.attributes = []; + } + if (!mode) { + state.node.attributes.push(mustacheCore.makeLiveBindingBranchRenderer(null, expression, copyState({ + filename: section.filename, + lineNo: lineNo + }))); + } else if (mode === '#' || mode === '^') { + if (!state.node.section) { + state.node.section = new TextSectionBuilder(filename); + } + makeRendererAndUpdateSection(state.node.section, mode, expression, lineNo); + } else { + throw new Error(mode + ' is currently not supported within a tag.'); + } + } else { + makeRendererAndUpdateSection(state.textContentOnly || section, mode, expression, lineNo); + } + }, + comment: function (text) { + section.add({ comment: text }); + }, + done: function (lineNo) { + } + }); + var renderer = section.compile(); + var scopifiedRenderer = ObservationRecorder.ignore(function (scope, options, nodeList) { + if (nodeList === undefined && canReflect.isListLike(options)) { + nodeList = options; + options = undefined; + } + if (options && !options.helpers && !options.partials && !options.tags) { + options = { helpers: options }; + } + canReflect.eachKey(options && options.helpers, function (helperValue) { + helperValue.requiresOptionsArgument = true; + }); + var templateContext = new TemplateContext(options); + canReflect.eachKey(inlinePartials, function (partial, partialName) { + canReflect.setKeyValue(templateContext.partials, partialName, partial); + }); + canReflect.setKeyValue(templateContext, 'view', scopifiedRenderer); + if (!(scope instanceof Scope)) { + scope = new Scope(templateContext).add(scope); + } else { + var templateContextScope = new Scope(templateContext); + templateContextScope._parent = scope._parent; + scope._parent = templateContextScope; + } + return renderer(scope.addLetContext(), nodeList); + }); + scopifiedRenderer[isViewSymbol] = true; + return scopifiedRenderer; + } + assign(stache, mustacheHelpers); + stache.safeString = function (text) { + return canReflect.assignSymbols({}, { + 'can.toDOM': function () { + return text; + } + }); + }; + stache.async = function (source) { + var iAi = getIntermediateAndImports(source); + var importPromises = iAi.imports.map(function (moduleName) { + return importer(moduleName); + }); + return Promise.all(importPromises).then(function () { + return stache(iAi.intermediate); + }); + }; + var templates = {}; + stache.from = mustacheCore.getTemplateById = function (id) { + if (!templates[id]) { + var el = DOCUMENT().getElementById(id); + if (el) { + templates[id] = stache('#' + id, el.innerHTML); + } + } + return templates[id]; + }; + stache.registerPartial = function (id, partial) { + templates[id] = typeof partial === 'string' ? stache(partial) : partial; + }; + stache.addBindings = viewCallbacks.attrs; + module.exports = namespace.stache = stache; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-key@1.2.0#utils*/ +define('can-key@1.2.0#utils', function (require, exports, module) { + 'use strict'; + var utils = { + isContainer: function (current) { + var type = typeof current; + return current && (type === 'object' || type === 'function'); + }, + strReplacer: /\{([^\}]+)\}/g, + parts: function (name) { + if (Array.isArray(name)) { + return name; + } else { + return typeof name !== 'undefined' ? (name + '').replace(/\[/g, '.').replace(/]/g, '').split('.') : []; + } + } + }; + module.exports = utils; +}); +/*can-key@1.2.0#get/get*/ +define('can-key@1.2.0#get/get', [ + 'require', + 'exports', + 'module', + 'can-reflect', + '../utils' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var utils = require('../utils'); + function get(obj, name) { + var parts = utils.parts(name); + var length = parts.length, current, i, container; + if (!length) { + return obj; + } + current = obj; + for (i = 0; i < length && utils.isContainer(current) && current !== null; i++) { + container = current; + current = canReflect.getKeyValue(container, parts[i]); + } + return current; + } + module.exports = get; +}); +/*can-control@4.4.1#can-control*/ +define('can-control@4.4.1#can-control', [ + 'require', + 'exports', + 'module', + 'can-construct', + 'can-namespace', + 'can-assign', + 'can-stache-key', + 'can-reflect', + 'can-observation', + 'can-event-queue/map/map', + 'can-log/dev/dev', + 'can-string', + 'can-key/get/get', + 'can-dom-mutate', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var Construct = require('can-construct'); + var namespace = require('can-namespace'); + var assign = require('can-assign'); + var observeReader = require('can-stache-key'); + var canReflect = require('can-reflect'); + var Observation = require('can-observation'); + var canEvent = require('can-event-queue/map/map'); + var dev = require('can-log/dev/dev'); + var string = require('can-string'); + var get = require('can-key/get/get'); + var domMutate = require('can-dom-mutate'); + var canSymbol = require('can-symbol'); + var controlsSymbol = canSymbol.for('can.controls'); + var processors; + var bind = function (el, ev, callback, queue) { + canEvent.on.call(el, ev, callback, queue); + return function () { + canEvent.off.call(el, ev, callback, queue); + }; + }, slice = [].slice, paramReplacer = /\{([^\}]+)\}/g, delegate = function (el, selector, ev, callback) { + canEvent.on.call(el, ev, selector, callback); + return function () { + canEvent.off.call(el, ev, selector, callback); + }; + }, binder = function (el, ev, callback, selector) { + return selector ? delegate(el, selector.trim(), ev, callback) : bind(el, ev, callback); + }, basicProcessor; + var Control = Construct.extend('Control', { + setup: function () { + Construct.setup.apply(this, arguments); + if (Control) { + var control = this, funcName; + control.actions = {}; + for (funcName in control.prototype) { + if (control._isAction(funcName)) { + control.actions[funcName] = control._action(funcName); + } + } + } + }, + _shifter: function (context, name) { + var method = typeof name === 'string' ? context[name] : name; + if (typeof method !== 'function') { + method = context[method]; + } + var Control = this; + function controlMethod() { + var wrapped = Control.wrapElement(this); + context.called = name; + return method.apply(context, [wrapped].concat(slice.call(arguments, 0))); + } + return controlMethod; + }, + _isAction: function (methodName) { + var val = this.prototype[methodName], type = typeof val; + return methodName !== 'constructor' && (type === 'function' || type === 'string' && typeof this.prototype[val] === 'function') && !!(Control.isSpecial(methodName) || processors[methodName] || /[^\w]/.test(methodName)); + }, + _action: function (methodName, options, controlInstance) { + var readyCompute, unableToBind; + paramReplacer.lastIndex = 0; + if (options || !paramReplacer.test(methodName)) { + var controlActionData = function () { + var delegate; + var name = methodName.replace(paramReplacer, function (matched, key) { + var value, parent; + if (this._isDelegate(options, key)) { + delegate = this._getDelegate(options, key); + return ''; + } + key = this._removeDelegateFromKey(key); + parent = this._lookup(options)[0]; + value = observeReader.read(parent, observeReader.reads(key), { readCompute: false }).value; + if (value === undefined && typeof window !== 'undefined') { + value = get(window, key); + } + if (!parent || !(canReflect.isObservableLike(parent) && canReflect.isMapLike(parent)) && !value) { + unableToBind = true; + return null; + } + if (typeof value === 'string') { + return value; + } else { + delegate = value; + return ''; + } + }.bind(this)); + name = name.trim(); + var parts = name.split(/\s+/g), event = parts.pop(); + return { + processor: this.processors[event] || basicProcessor, + parts: [ + name, + parts.join(' '), + event + ], + delegate: delegate || undefined + }; + }; + readyCompute = new Observation(controlActionData, this); + if (controlInstance) { + var handler = function (actionData) { + controlInstance._bindings.control[methodName](controlInstance.element); + controlInstance._bindings.control[methodName] = actionData.processor(actionData.delegate || controlInstance.element, actionData.parts[2], actionData.parts[1], methodName, controlInstance); + }; + canReflect.onValue(readyCompute, handler, 'mutate'); + controlInstance._bindings.readyComputes[methodName] = { + compute: readyCompute, + handler: handler + }; + } + return readyCompute.get(); + } + }, + _lookup: function (options) { + return [ + options, + window + ]; + }, + _removeDelegateFromKey: function (key) { + return key; + }, + _isDelegate: function (options, key) { + return key === 'element'; + }, + _getDelegate: function (options, key) { + return undefined; + }, + processors: {}, + defaults: {}, + convertElement: function (element) { + element = typeof element === 'string' ? document.querySelector(element) : element; + return this.wrapElement(element); + }, + wrapElement: function (el) { + return el; + }, + unwrapElement: function (el) { + return el; + }, + isSpecial: function (eventName) { + return eventName === 'inserted' || eventName === 'removed'; + } + }, { + setup: function (element, options) { + var cls = this.constructor, pluginname = cls.pluginName || cls.shortName, arr; + if (!element) { + throw new Error('Creating an instance of a named control without passing an element'); + } + this.element = cls.convertElement(element); + if (pluginname && pluginname !== 'Control' && this.element.classList) { + this.element.classList.add(pluginname); + } + arr = this.element[controlsSymbol]; + if (!arr) { + arr = []; + this.element[controlsSymbol] = arr; + } + arr.push(this); + if (canReflect.isObservableLike(options) && canReflect.isMapLike(options)) { + for (var prop in cls.defaults) { + if (!options.hasOwnProperty(prop)) { + observeReader.set(options, prop, cls.defaults[prop]); + } + } + this.options = options; + } else { + this.options = assign(assign({}, cls.defaults), options); + } + this.on(); + return [ + this.element, + this.options + ]; + }, + on: function (el, selector, eventName, func) { + if (!el) { + this.off(); + var cls = this.constructor, bindings = this._bindings, actions = cls.actions, element = this.constructor.unwrapElement(this.element), destroyCB = Control._shifter(this, 'destroy'), funcName, ready; + for (funcName in actions) { + if (actions.hasOwnProperty(funcName)) { + ready = actions[funcName] || cls._action(funcName, this.options, this); + if (ready) { + bindings.control[funcName] = ready.processor(ready.delegate || element, ready.parts[2], ready.parts[1], funcName, this); + } + } + } + var removalDisposal = domMutate.onNodeRemoval(element, function () { + var doc = element.ownerDocument; + var ownerNode = doc.contains ? doc : doc.documentElement; + if (!ownerNode || ownerNode.contains(element) === false) { + destroyCB(); + } + }); + bindings.user.push(function () { + if (removalDisposal) { + removalDisposal(); + removalDisposal = undefined; + } + }); + return bindings.user.length; + } + if (typeof el === 'string') { + func = eventName; + eventName = selector; + selector = el; + el = this.element; + } + if (func === undefined) { + func = eventName; + eventName = selector; + selector = null; + } + if (typeof func === 'string') { + func = Control._shifter(this, func); + } + this._bindings.user.push(binder(el, eventName, func, selector)); + return this._bindings.user.length; + }, + off: function () { + var el = this.constructor.unwrapElement(this.element), bindings = this._bindings; + if (bindings) { + (bindings.user || []).forEach(function (value) { + value(el); + }); + canReflect.eachKey(bindings.control || {}, function (value) { + value(el); + }); + canReflect.eachKey(bindings.readyComputes || {}, function (value) { + canReflect.offValue(value.compute, value.handler, 'mutate'); + }); + } + this._bindings = { + user: [], + control: {}, + readyComputes: {} + }; + }, + destroy: function () { + if (this.element === null) { + return; + } + var Class = this.constructor, pluginName = Class.pluginName || Class.shortName && string.underscore(Class.shortName), controls; + this.off(); + if (pluginName && pluginName !== 'can_control' && this.element.classList) { + this.element.classList.remove(pluginName); + } + controls = this.element[controlsSymbol]; + if (controls) { + controls.splice(controls.indexOf(this), 1); + } + this.element = null; + } + }); + processors = Control.processors; + basicProcessor = function (el, event, selector, methodName, control) { + return binder(el, event, Control._shifter(control, methodName), selector); + }; + [ + 'beforeremove', + 'change', + 'click', + 'contextmenu', + 'dblclick', + 'keydown', + 'keyup', + 'keypress', + 'mousedown', + 'mousemove', + 'mouseout', + 'mouseover', + 'mouseup', + 'reset', + 'resize', + 'scroll', + 'select', + 'submit', + 'focusin', + 'focusout', + 'mouseenter', + 'mouseleave', + 'touchstart', + 'touchmove', + 'touchcancel', + 'touchend', + 'touchleave', + 'inserted', + 'removed', + 'dragstart', + 'dragenter', + 'dragover', + 'dragleave', + 'drag', + 'drop', + 'dragend' + ].forEach(function (v) { + processors[v] = basicProcessor; + }); + module.exports = namespace.Control = Control; +}); +/*can-component@4.4.9#control/control*/ +define('can-component@4.4.9#control/control', [ + 'require', + 'exports', + 'module', + 'can-control', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var Control = require('can-control'); + var canReflect = require('can-reflect'); + var paramReplacer = /\{([^\}]+)\}/g; + var ComponentControl = Control.extend({ + _lookup: function (options) { + return [ + options.scope, + options, + window + ]; + }, + _removeDelegateFromKey: function (key) { + return key.replace(/^(scope|^viewModel)\./, ''); + }, + _isDelegate: function (options, key) { + return key === 'scope' || key === 'viewModel'; + }, + _getDelegate: function (options, key) { + return options[key]; + }, + _action: function (methodName, options, controlInstance) { + var hasObjectLookup; + paramReplacer.lastIndex = 0; + hasObjectLookup = paramReplacer.test(methodName); + if (!controlInstance && hasObjectLookup) { + return; + } else { + return Control._action.apply(this, arguments); + } + } + }, { + setup: function (el, options) { + this.scope = options.scope; + this.viewModel = options.viewModel; + return Control.prototype.setup.call(this, el, options); + }, + off: function () { + if (this._bindings) { + canReflect.eachKey(this._bindings.readyComputes || {}, function (value) { + canReflect.offValue(value.compute, value.handler); + }); + } + Control.prototype.off.apply(this, arguments); + this._bindings.readyComputes = {}; + }, + destroy: function () { + Control.prototype.destroy.apply(this, arguments); + if (typeof this.options.destroy === 'function') { + this.options.destroy.apply(this, arguments); + } + } + }); + module.exports = ComponentControl; +}); +/*can-bind@1.1.1#can-bind*/ +define('can-bind@1.1.1#can-bind', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-symbol', + 'can-namespace', + 'can-queues', + 'can-assign' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var namespace = require('can-namespace'); + var queues = require('can-queues'); + var canAssign = require('can-assign'); + var getChangesSymbol = canSymbol.for('can.getChangesDependencyRecord'); + var getValueSymbol = canSymbol.for('can.getValue'); + var onValueSymbol = canSymbol.for('can.onValue'); + var setValueSymbol = canSymbol.for('can.setValue'); + function defaultSetValue(newValue, observable) { + canReflect.setValue(observable, newValue); + } + function turnOffListeningAndUpdate(listenToObservable, updateObservable, updateFunction, queue) { + if (listenToObservable[onValueSymbol]) { + canReflect.offValue(listenToObservable, updateFunction, queue); + } + } + function turnOnListeningAndUpdate(listenToObservable, updateObservable, updateFunction, queue) { + if (listenToObservable[onValueSymbol]) { + canReflect.onValue(listenToObservable, updateFunction, queue); + } + } + function Semaphore(binding, type) { + this.value = 0; + this._binding = binding; + this._type = type; + } + canAssign(Semaphore.prototype, { + decrement: function () { + this.value -= 1; + }, + increment: function (args) { + this._incremented = true; + this.value += 1; + } + }); + function Bind(options) { + this._options = options; + if (options.queue === undefined) { + options.queue = 'domUI'; + } + if (options.cycles > 0 === false) { + options.cycles = 0; + } + options.onInitDoNotUpdateChild = typeof options.onInitDoNotUpdateChild === 'boolean' ? options.onInitDoNotUpdateChild : false; + options.onInitSetUndefinedParentIfChildIsDefined = typeof options.onInitSetUndefinedParentIfChildIsDefined === 'boolean' ? options.onInitSetUndefinedParentIfChildIsDefined : true; + var childSemaphore = new Semaphore(this, 'child'); + var parentSemaphore = new Semaphore(this, 'parent'); + var childToParent = true; + if (typeof options.childToParent === 'boolean') { + childToParent = options.childToParent; + } else if (options.child[getValueSymbol] == null) { + childToParent = false; + } else if (options.setParent === undefined && options.parent[setValueSymbol] == null) { + childToParent = false; + } + var parentToChild = true; + if (typeof options.parentToChild === 'boolean') { + parentToChild = options.parentToChild; + } else if (options.parent[getValueSymbol] == null) { + parentToChild = false; + } else if (options.setChild === undefined && options.child[setValueSymbol] == null) { + parentToChild = false; + } + if (childToParent === false && parentToChild === false) { + throw new Error('Neither the child nor parent will be updated; this is a no-way binding'); + } + this._childToParent = childToParent; + this._parentToChild = parentToChild; + if (options.setChild === undefined) { + options.setChild = defaultSetValue; + } + if (options.setParent === undefined) { + options.setParent = defaultSetValue; + } + if (options.priority !== undefined) { + canReflect.setPriority(options.child, options.priority); + canReflect.setPriority(options.parent, options.priority); + } + var allowedUpdates = options.cycles * 2; + var allowedChildUpdates = allowedUpdates + (options.sticky === 'childSticksToParent' ? 1 : 0); + var allowedParentUpdates = allowedUpdates + (options.sticky === 'parentSticksToChild' ? 1 : 0); + this._bindingState = { + child: false, + parent: false + }; + this._updateChild = function (newValue) { + updateValue.call(this, { + bindingState: this._bindingState, + newValue: newValue, + debugObservableName: 'child', + debugPartnerName: 'parent', + observable: options.child, + setValue: options.setChild, + semaphore: childSemaphore, + allowedUpdates: allowedChildUpdates, + sticky: options.sticky === 'parentSticksToChild', + partner: options.parent, + setPartner: options.setParent, + partnerSemaphore: parentSemaphore + }); + }.bind(this); + this._updateParent = function (newValue) { + updateValue.call(this, { + bindingState: this._bindingState, + newValue: newValue, + debugObservableName: 'parent', + debugPartnerName: 'child', + observable: options.parent, + setValue: options.setParent, + semaphore: parentSemaphore, + allowedUpdates: allowedParentUpdates, + sticky: options.sticky === 'childSticksToParent', + partner: options.child, + setPartner: options.setChild, + partnerSemaphore: childSemaphore + }); + }.bind(this); + } + Object.defineProperty(Bind.prototype, 'parentValue', { + get: function () { + return canReflect.getValue(this._options.parent); + } + }); + canAssign(Bind.prototype, { + start: function () { + var childValue; + var options = this._options; + var parentValue; + this.startParent(); + this.startChild(); + if (this._childToParent === true && this._parentToChild === true) { + parentValue = canReflect.getValue(options.parent); + if (parentValue === undefined) { + childValue = canReflect.getValue(options.child); + if (childValue === undefined) { + if (options.onInitDoNotUpdateChild === false) { + this._updateChild(parentValue); + } + } else if (options.onInitSetUndefinedParentIfChildIsDefined === true) { + this._updateParent(childValue); + } + } else { + if (options.onInitDoNotUpdateChild === false) { + this._updateChild(parentValue); + } + } + } else if (this._childToParent === true) { + childValue = canReflect.getValue(options.child); + this._updateParent(childValue); + } else if (this._parentToChild === true) { + if (options.onInitDoNotUpdateChild === false) { + parentValue = canReflect.getValue(options.parent); + this._updateChild(parentValue); + } + } + }, + startChild: function () { + if (this._bindingState.child === false && this._childToParent === true) { + var options = this._options; + this._bindingState.child = true; + turnOnListeningAndUpdate(options.child, options.parent, this._updateParent, options.queue); + } + }, + startParent: function () { + if (this._bindingState.parent === false && this._parentToChild === true) { + var options = this._options; + this._bindingState.parent = true; + turnOnListeningAndUpdate(options.parent, options.child, this._updateChild, options.queue); + } + }, + stop: function () { + var bindingState = this._bindingState; + var options = this._options; + if (bindingState.parent === true && this._parentToChild === true) { + bindingState.parent = false; + turnOffListeningAndUpdate(options.parent, options.child, this._updateChild, options.queue); + } + if (bindingState.child === true && this._childToParent === true) { + bindingState.child = false; + turnOffListeningAndUpdate(options.child, options.parent, this._updateParent, options.queue); + } + } + }); + function updateValue(args) { + var bindingState = args.bindingState; + if (bindingState.child === false && bindingState.parent === false) { + return; + } + var semaphore = args.semaphore; + if (semaphore.value + args.partnerSemaphore.value <= args.allowedUpdates) { + queues.batch.start(); + semaphore.increment(args); + args.setValue(args.newValue, args.observable); + queues.mutateQueue.enqueue(semaphore.decrement, semaphore, []); + queues.batch.stop(); + if (args.sticky) { + var observableValue = canReflect.getValue(args.observable); + if (observableValue !== canReflect.getValue(args.partner)) { + args.setPartner(observableValue, args.partner); + } + } + } else { + } + } + module.exports = namespace.Bind = Bind; +}); +/*can-view-model@4.0.1#can-view-model*/ +define('can-view-model@4.0.1#can-view-model', [ + 'require', + 'exports', + 'module', + 'can-simple-map', + 'can-namespace', + 'can-globals/document/document', + 'can-reflect', + 'can-symbol' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var SimpleMap = require('can-simple-map'); + var ns = require('can-namespace'); + var getDocument = require('can-globals/document/document'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var viewModelSymbol = canSymbol.for('can.viewModel'); + module.exports = ns.viewModel = function (el, attr, val) { + if (typeof el === 'string') { + el = getDocument().querySelector(el); + } else if (canReflect.isListLike(el) && !el.nodeType) { + el = el[0]; + } + if (canReflect.isObservableLike(attr) && canReflect.isMapLike(attr)) { + el[viewModelSymbol] = attr; + return; + } + var scope = el[viewModelSymbol]; + if (!scope) { + scope = new SimpleMap(); + el[viewModelSymbol] = scope; + } + switch (arguments.length) { + case 0: + case 1: + return scope; + case 2: + return canReflect.getKeyValue(scope, attr); + default: + canReflect.setKeyValue(scope, attr, val); + return el; + } + }; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-attribute-observable@1.1.7#event*/ +define('can-attribute-observable@1.1.7#event', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-dom-events', + 'can-dom-events/helpers/util' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var domEvents = require('can-dom-events'); + var isDomEventTarget = require('can-dom-events/helpers/util').isDomEventTarget; + var canEvent = { + on: function on(eventName, handler, queue) { + if (isDomEventTarget(this)) { + domEvents.addEventListener(this, eventName, handler, queue); + } else { + canReflect.onKeyValue(this, eventName, handler, queue); + } + }, + off: function off(eventName, handler, queue) { + if (isDomEventTarget(this)) { + domEvents.removeEventListener(this, eventName, handler, queue); + } else { + canReflect.offKeyValue(this, eventName, handler, queue); + } + }, + one: function one(event, handler, queue) { + var one = function () { + canEvent.off.call(this, event, one, queue); + return handler.apply(this, arguments); + }; + canEvent.on.call(this, event, one, queue); + return this; + } + }; + module.exports = canEvent; +}); +/*can-attribute-observable@1.1.7#get-event-name*/ +define('can-attribute-observable@1.1.7#get-event-name', [ + 'require', + 'exports', + 'module', + './behaviors' +], function (require, exports, module) { + 'use strict'; + var attr = require('./behaviors'); + var isRadioInput = function isRadioInput(el) { + return el.nodeName.toLowerCase() === 'input' && el.type === 'radio'; + }; + var isValidProp = function isValidProp(prop, bindingData) { + return prop === 'checked' && !bindingData.legacyBindings; + }; + module.exports = function getEventName(el, prop, bindingData) { + var event = 'change'; + if (isRadioInput(el) && isValidProp(prop, bindingData)) { + event = 'can-attribute-observable-radiochange'; + } + if (attr.findSpecialListener(prop)) { + event = prop; + } + return event; + }; +}); +/*can-event-dom-radiochange@2.2.0#can-event-dom-radiochange*/ +define('can-event-dom-radiochange@2.2.0#can-event-dom-radiochange', [ + 'require', + 'exports', + 'module', + 'can-globals/document/document', + 'can-namespace' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var getDocument = require('can-globals/document/document'); + var namespace = require('can-namespace'); + function getRoot() { + return getDocument().documentElement; + } + function findParentForm(el) { + while (el) { + if (el.nodeName === 'FORM') { + break; + } + el = el.parentNode; + } + return el; + } + function shouldReceiveEventFromRadio(source, dest) { + var name = source.getAttribute('name'); + return name && name === dest.getAttribute('name') && findParentForm(source) === findParentForm(dest); + } + function isRadioInput(el) { + return el.nodeName === 'INPUT' && el.type === 'radio'; + } + function attachRootListener(domEvents, eventTypeTargets) { + var root = getRoot(); + var newListener = function (event) { + var target = event.target; + if (!isRadioInput(target)) { + return; + } + for (var eventType in eventTypeTargets) { + var newEvent = { type: eventType }; + var listeningNodes = eventTypeTargets[eventType]; + listeningNodes.forEach(function (el) { + if (shouldReceiveEventFromRadio(target, el)) { + domEvents.dispatch(el, newEvent, false); + } + }); + } + }; + domEvents.addEventListener(root, 'change', newListener); + return newListener; + } + function detachRootListener(domEvents, listener) { + var root = getRoot(); + domEvents.removeEventListener(root, 'change', listener); + } + var radioChangeEvent = { + defaultEventType: 'radiochange', + addEventListener: function (target, eventType, handler) { + if (!isRadioInput(target)) { + throw new Error('Listeners for ' + eventType + ' must be radio inputs'); + } + var eventTypeTrackedRadios = radioChangeEvent._eventTypeTrackedRadios; + if (!eventTypeTrackedRadios) { + eventTypeTrackedRadios = radioChangeEvent._eventTypeTrackedRadios = {}; + if (!radioChangeEvent._rootListener) { + radioChangeEvent._rootListener = attachRootListener(this, eventTypeTrackedRadios); + } + } + var trackedRadios = radioChangeEvent._eventTypeTrackedRadios[eventType]; + if (!trackedRadios) { + trackedRadios = radioChangeEvent._eventTypeTrackedRadios[eventType] = new Set(); + } + trackedRadios.add(target); + target.addEventListener(eventType, handler); + }, + removeEventListener: function (target, eventType, handler) { + target.removeEventListener(eventType, handler); + var eventTypeTrackedRadios = radioChangeEvent._eventTypeTrackedRadios; + if (!eventTypeTrackedRadios) { + return; + } + var trackedRadios = eventTypeTrackedRadios[eventType]; + if (!trackedRadios) { + return; + } + trackedRadios.delete(target); + if (trackedRadios.size === 0) { + delete eventTypeTrackedRadios[eventType]; + for (var key in eventTypeTrackedRadios) { + if (eventTypeTrackedRadios.hasOwnProperty(key)) { + return; + } + } + delete radioChangeEvent._eventTypeTrackedRadios; + detachRootListener(this, radioChangeEvent._rootListener); + delete radioChangeEvent._rootListener; + } + } + }; + module.exports = namespace.domEventRadioChange = radioChangeEvent; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-attribute-observable@1.1.7#can-attribute-observable*/ +define('can-attribute-observable@1.1.7#can-attribute-observable', [ + 'require', + 'exports', + 'module', + 'can-queues', + './event', + 'can-reflect', + 'can-observation', + './behaviors', + './get-event-name', + 'can-reflect-dependencies', + 'can-observation-recorder', + 'can-simple-observable/settable/settable', + 'can-assign', + 'can-dom-events', + 'can-event-dom-radiochange' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var queues = require('can-queues'); + var canEvent = require('./event'); + var canReflect = require('can-reflect'); + var Observation = require('can-observation'); + var attr = require('./behaviors'); + var getEventName = require('./get-event-name'); + var canReflectDeps = require('can-reflect-dependencies'); + var ObservationRecorder = require('can-observation-recorder'); + var SettableObservable = require('can-simple-observable/settable/settable'); + var canAssign = require('can-assign'); + var domEvents = require('can-dom-events'); + var radioChangeEvent = require('can-event-dom-radiochange'); + var internalRadioChangeEventType = 'can-attribute-observable-radiochange'; + domEvents.addEvent(radioChangeEvent, internalRadioChangeEventType); + var isSelect = function isSelect(el) { + return el.nodeName.toLowerCase() === 'select'; + }; + var isMultipleSelect = function isMultipleSelect(el, prop) { + return isSelect(el) && prop === 'value' && el.multiple; + }; + var slice = Array.prototype.slice; + function canUtilAEL() { + var args = slice.call(arguments, 0); + args.unshift(this); + return domEvents.addEventListener.apply(null, args); + } + function canUtilREL() { + var args = slice.call(arguments, 0); + args.unshift(this); + return domEvents.removeEventListener.apply(null, args); + } + function AttributeObservable(el, prop, bindingData, event) { + this.el = el; + this.bound = false; + this.bindingData = bindingData; + this.prop = isMultipleSelect(el, prop) ? 'values' : prop; + this.event = event || getEventName(el, prop, bindingData); + this.handler = this.handler.bind(this); + } + AttributeObservable.prototype = Object.create(SettableObservable.prototype); + canAssign(AttributeObservable.prototype, { + constructor: AttributeObservable, + get: function get() { + if (ObservationRecorder.isRecording()) { + ObservationRecorder.add(this); + if (!this.bound) { + Observation.temporarilyBind(this); + } + } + var value = attr.get(this.el, this.prop); + if (typeof value === 'function') { + value = value.bind(this.el); + } + return value; + }, + set: function set(newVal) { + var setterDispatchedEvents = attr.setAttrOrProp(this.el, this.prop, newVal); + if (!setterDispatchedEvents) { + this._value = newVal; + } + return newVal; + }, + handler: function handler(newVal, event) { + var old = this._value; + var queuesArgs = []; + this._value = attr.get(this.el, this.prop); + if (this._value !== old) { + queuesArgs = [ + this.handlers.getNode([]), + this, + [ + newVal, + old + ] + ]; + queues.enqueueByQueue.apply(queues, queuesArgs); + } + }, + onBound: function onBound() { + var observable = this; + observable.bound = true; + observable._handler = function (event) { + observable.handler(attr.get(observable.el, observable.prop), event); + }; + if (observable.event === internalRadioChangeEventType) { + canEvent.on.call(observable.el, 'change', observable._handler); + } + var specialBinding = attr.findSpecialListener(observable.prop); + if (specialBinding) { + observable._specialDisposal = specialBinding.call(observable.el, observable.prop, observable._handler, canUtilAEL); + } + canEvent.on.call(observable.el, observable.event, observable._handler); + this._value = attr.get(this.el, this.prop); + }, + onUnbound: function onUnbound() { + var observable = this; + observable.bound = false; + if (observable.event === internalRadioChangeEventType) { + canEvent.off.call(observable.el, 'change', observable._handler); + } + if (observable._specialDisposal) { + observable._specialDisposal.call(observable.el, canUtilREL); + observable._specialDisposal = null; + } + canEvent.off.call(observable.el, observable.event, observable._handler); + }, + valueHasDependencies: function valueHasDependencies() { + return true; + }, + getValueDependencies: function getValueDependencies() { + var m = new Map(); + var s = new Set(); + s.add(this.prop); + m.set(this.el, s); + return { keyDependencies: m }; + } + }); + canReflect.assignSymbols(AttributeObservable.prototype, { + 'can.isMapLike': false, + 'can.getValue': AttributeObservable.prototype.get, + 'can.setValue': AttributeObservable.prototype.set, + 'can.onValue': AttributeObservable.prototype.on, + 'can.offValue': AttributeObservable.prototype.off, + 'can.valueHasDependencies': AttributeObservable.prototype.hasDependencies, + 'can.getValueDependencies': AttributeObservable.prototype.getValueDependencies + }); + module.exports = AttributeObservable; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-stache-bindings@4.6.4#can-stache-bindings*/ +define('can-stache-bindings@4.6.4#can-stache-bindings', [ + 'require', + 'exports', + 'module', + 'can-bind', + 'can-stache/src/expression', + 'can-view-callbacks', + 'can-view-model', + 'can-stache-key', + 'can-observation-recorder', + 'can-simple-observable', + 'can-assign', + 'can-log/dev/dev', + 'can-dom-mutate', + 'can-dom-data-state', + 'can-symbol', + 'can-reflect', + 'can-reflect-dependencies', + 'can-attribute-encoder', + 'can-queues', + 'can-simple-observable/setter/setter', + 'can-attribute-observable', + 'can-view-scope/make-compute-like', + 'can-view-nodelist', + 'can-attribute-observable/event' +], function (require, exports, module) { + 'use strict'; + var Bind = require('can-bind'); + var expression = require('can-stache/src/expression'); + var viewCallbacks = require('can-view-callbacks'); + var canViewModel = require('can-view-model'); + var observeReader = require('can-stache-key'); + var ObservationRecorder = require('can-observation-recorder'); + var SimpleObservable = require('can-simple-observable'); + var assign = require('can-assign'); + var dev = require('can-log/dev/dev'); + var domMutate = require('can-dom-mutate'); + var domData = require('can-dom-data-state'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + var canReflectDeps = require('can-reflect-dependencies'); + var encoder = require('can-attribute-encoder'); + var queues = require('can-queues'); + var SettableObservable = require('can-simple-observable/setter/setter'); + var AttributeObservable = require('can-attribute-observable'); + var makeCompute = require('can-view-scope/make-compute-like'); + var ViewNodeList = require('can-view-nodelist'); + var canEvent = require('can-attribute-observable/event'); + var bindings = new Map(); + var onMatchStr = 'on:', vmMatchStr = 'vm:', elMatchStr = 'el:', byMatchStr = ':by:', toMatchStr = ':to', fromMatchStr = ':from', bindMatchStr = ':bind', viewModelBindingStr = 'viewModel', attributeBindingStr = 'attribute', scopeBindingStr = 'scope', viewModelOrAttributeBindingStr = 'viewModelOrAttribute'; + var throwOnlyOneTypeOfBindingError = function () { + throw new Error('can-stache-bindings - you can not have contextual bindings ( this:from=\'value\' ) and key bindings ( prop:from=\'value\' ) on one element.'); + }; + var checkBindingState = function (bindingState, bindingInfo) { + var isSettingOnViewModel = bindingInfo.parentToChild && bindingInfo.child === viewModelBindingStr; + if (isSettingOnViewModel) { + var bindingName = bindingInfo.childName; + var isSettingViewModel = isSettingOnViewModel && (bindingName === 'this' || bindingName === '.'); + if (isSettingViewModel) { + if (bindingState.isSettingViewModel || bindingState.isSettingOnViewModel) { + throwOnlyOneTypeOfBindingError(); + } else { + return { + isSettingViewModel: true, + initialViewModelData: undefined + }; + } + } else { + if (bindingState.isSettingViewModel) { + throwOnlyOneTypeOfBindingError(); + } else { + return { + isSettingOnViewModel: true, + initialViewModelData: bindingState.initialViewModelData + }; + } + } + } else { + return bindingState; + } + }; + var makeScopeFromEvent = function (element, event, viewModel, args, data) { + var specialValues = { + element: element, + event: event, + viewModel: viewModel, + arguments: args + }; + return data.scope.add(specialValues, { special: true }); + }; + var runEventCallback = function (el, ev, data, scope, expr, attributeName, attrVal) { + var updateFn = function () { + var value = expr.value(scope, { doNotWrapInObservation: true }); + value = canReflect.isValueLike(value) ? canReflect.getValue(value) : value; + return typeof value === 'function' ? value(el) : value; + }; + queues.batch.start(); + var mutateQueueArgs = []; + mutateQueueArgs = [ + updateFn, + null, + null, + {} + ]; + queues.mutateQueue.enqueue.apply(queues.mutateQueue, mutateQueueArgs); + queues.batch.stop(); + }; + var behaviors = { + viewModel: function (el, tagData, makeViewModel, initialViewModelData, staticDataBindingsOnly) { + var viewModel, onCompleteBindings = [], onTeardowns = {}, bindingInfos = {}, attributeViewModelBindings = assign({}, initialViewModelData), bindingsState = { + isSettingOnViewModel: false, + isSettingViewModel: false, + initialViewModelData: initialViewModelData || {} + }, hasDataBinding = false; + canReflect.each(el.attributes || [], function (node) { + var dataBinding = makeDataBinding(node, el, { + templateType: tagData.templateType, + scope: tagData.scope, + getViewModel: function () { + return viewModel; + }, + attributeViewModelBindings: attributeViewModelBindings, + alreadyUpdatedChild: true, + nodeList: tagData.parentNodeList, + favorViewModel: true + }); + if (dataBinding) { + var bindingInfo = dataBinding.bindingInfo; + bindingsState = checkBindingState(bindingsState, bindingInfo); + hasDataBinding = true; + if (bindingInfo.parentToChild) { + var parentValue = bindingInfo.stickyParentToChild ? makeCompute(dataBinding.parent) : dataBinding.canBinding.parentValue; + if (parentValue !== undefined) { + if (bindingsState.isSettingViewModel) { + bindingsState.initialViewModelData = parentValue; + } else { + bindingsState.initialViewModelData[cleanVMName(bindingInfo.childName, tagData.scope)] = parentValue; + } + } + } + onCompleteBindings.push(dataBinding.canBinding.start.bind(dataBinding.canBinding)); + onTeardowns[node.name] = dataBinding.canBinding.stop.bind(dataBinding.canBinding); + } + }); + if (staticDataBindingsOnly && !hasDataBinding) { + return; + } + viewModel = makeViewModel(bindingsState.initialViewModelData, hasDataBinding, bindingsState); + for (var i = 0, len = onCompleteBindings.length; i < len; i++) { + onCompleteBindings[i](); + } + var attributeDisposal; + if (!bindingsState.isSettingViewModel) { + attributeDisposal = domMutate.onNodeAttributeChange(el, function (ev) { + var attrName = ev.attributeName, value = el.getAttribute(attrName); + if (onTeardowns[attrName]) { + onTeardowns[attrName](); + } + var parentBindingWasAttribute = bindingInfos[attrName] && bindingInfos[attrName].parent === attributeBindingStr; + if (value !== null || parentBindingWasAttribute) { + var dataBinding = makeDataBinding({ + name: attrName, + value: value + }, el, { + templateType: tagData.templateType, + scope: tagData.scope, + getViewModel: function () { + return viewModel; + }, + attributeViewModelBindings: attributeViewModelBindings, + initializeValues: true, + nodeList: tagData.parentNodeList + }); + if (dataBinding) { + dataBinding.canBinding.start(); + bindingInfos[attrName] = dataBinding.bindingInfo; + onTeardowns[attrName] = dataBinding.canBinding.stop.bind(dataBinding.canBinding); + } + } + }); + } + return function () { + if (attributeDisposal) { + attributeDisposal(); + attributeDisposal = undefined; + } + for (var attrName in onTeardowns) { + onTeardowns[attrName](); + } + }; + }, + data: function (el, attrData) { + if (domData.get.call(el, 'preventDataBindings')) { + return; + } + var viewModel, getViewModel = ObservationRecorder.ignore(function () { + return viewModel || (viewModel = canViewModel(el)); + }), teardown, attributeDisposal, removedDisposal; + var dataBinding = makeDataBinding({ + name: attrData.attributeName, + value: el.getAttribute(attrData.attributeName), + nodeList: attrData.nodeList + }, el, { + templateType: attrData.templateType, + scope: attrData.scope, + getViewModel: getViewModel, + syncChildWithParent: false + }); + dataBinding.canBinding.start(); + var attributeListener = function (ev) { + var attrName = ev.attributeName, value = el.getAttribute(attrName); + if (attrName === attrData.attributeName) { + if (teardown) { + teardown(); + } + if (value !== null) { + var dataBinding = makeDataBinding({ + name: attrName, + value: value + }, el, { + templateType: attrData.templateType, + scope: attrData.scope, + getViewModel: getViewModel, + initializeValues: true, + nodeList: attrData.nodeList, + syncChildWithParent: false + }); + if (dataBinding) { + dataBinding.canBinding.start(); + teardown = dataBinding.canBinding.stop.bind(dataBinding.canBinding); + } + teardown = dataBinding.onTeardown; + } + } + }; + var tearItAllDown = function () { + if (teardown) { + teardown(); + teardown = undefined; + } + if (removedDisposal) { + removedDisposal(); + removedDisposal = undefined; + } + if (attributeDisposal) { + attributeDisposal(); + attributeDisposal = undefined; + } + }; + if (attrData.nodeList) { + ViewNodeList.register([], tearItAllDown, attrData.nodeList, false); + } + teardown = dataBinding.canBinding.stop.bind(dataBinding.canBinding); + attributeDisposal = domMutate.onNodeAttributeChange(el, attributeListener); + removedDisposal = domMutate.onNodeRemoval(el, function () { + var doc = el.ownerDocument; + var ownerNode = doc.contains ? doc : doc.documentElement; + if (!ownerNode || ownerNode.contains(el) === false) { + tearItAllDown(); + } + }); + }, + event: function (el, data) { + var attributeName = encoder.decode(data.attributeName), event, bindingContext; + if (attributeName.indexOf(toMatchStr + ':') !== -1 || attributeName.indexOf(fromMatchStr + ':') !== -1 || attributeName.indexOf(bindMatchStr + ':') !== -1) { + return this.data(el, data); + } + if (startsWith.call(attributeName, onMatchStr)) { + event = attributeName.substr(onMatchStr.length); + var viewModel = el[canSymbol.for('can.viewModel')]; + var byParent = data.scope; + if (startsWith.call(event, elMatchStr)) { + event = event.substr(elMatchStr.length); + bindingContext = el; + } else { + if (startsWith.call(event, vmMatchStr)) { + event = event.substr(vmMatchStr.length); + bindingContext = viewModel; + byParent = viewModel; + } else { + bindingContext = viewModel || el; + } + var byIndex = event.indexOf(byMatchStr); + if (byIndex >= 0) { + bindingContext = byParent.get(event.substr(byIndex + byMatchStr.length)); + event = event.substr(0, byIndex); + } + } + } else { + throw new Error('can-stache-bindings - unsupported event bindings ' + attributeName); + } + var handler = function (ev) { + var attrVal = el.getAttribute(encoder.encode(attributeName)); + if (!attrVal) { + return; + } + var viewModel = canViewModel(el); + var expr = expression.parse(attrVal, { + lookupRule: function () { + return expression.Lookup; + }, + methodRule: 'call' + }); + var runScope = makeScopeFromEvent(el, ev, viewModel, arguments, data); + if (expr instanceof expression.Hashes) { + var hashExprs = expr.hashExprs; + var key = Object.keys(hashExprs)[0]; + var value = expr.hashExprs[key].value(runScope); + var isObservableValue = canReflect.isObservableLike(value) && canReflect.isValueLike(value); + runScope.set(key, isObservableValue ? canReflect.getValue(value) : value); + } else if (expr instanceof expression.Call) { + runEventCallback(el, ev, data, runScope, expr, attributeName, attrVal); + } else { + throw new Error('can-stache-bindings: Event bindings must be a call expression. Make sure you have a () in ' + data.attributeName + '=' + JSON.stringify(attrVal)); + } + }; + var attributesDisposal, removalDisposal; + var attributesHandler = function (ev) { + var isEventAttribute = ev.attributeName === attributeName; + var isRemoved = !el.getAttribute(attributeName); + var isEventAttributeRemoved = isEventAttribute && isRemoved; + if (isEventAttributeRemoved) { + unbindEvent(); + } + }; + var removalHandler = function () { + var doc = el.ownerDocument; + var ownerNode = doc.contains ? doc : doc.documentElement; + if (!ownerNode || !ownerNode.contains(el)) { + unbindEvent(); + } + }; + var unbindEvent = function () { + canEvent.off.call(bindingContext, event, handler); + if (attributesDisposal) { + attributesDisposal(); + attributesDisposal = undefined; + } + if (removalDisposal) { + removalDisposal(); + removalDisposal = undefined; + } + }; + canEvent.on.call(bindingContext, event, handler); + attributesDisposal = domMutate.onNodeAttributeChange(el, attributesHandler); + removalDisposal = domMutate.onNodeRemoval(el, removalHandler); + } + }; + bindings.set(/[\w\.:]+:to$/, behaviors.data); + bindings.set(/[\w\.:]+:from$/, behaviors.data); + bindings.set(/[\w\.:]+:bind$/, behaviors.data); + bindings.set(/[\w\.:]+:raw$/, behaviors.data); + bindings.set(/[\w\.:]+:to:on:[\w\.:]+/, behaviors.data); + bindings.set(/[\w\.:]+:from:on:[\w\.:]+/, behaviors.data); + bindings.set(/[\w\.:]+:bind:on:[\w\.:]+/, behaviors.data); + bindings.set(/on:[\w\.:]+/, behaviors.event); + var getObservableFrom = { + viewModelOrAttribute: function (el, scope, vmNameOrProp, bindingData, mustBeGettable, stickyCompute, event) { + var viewModel = el[canSymbol.for('can.viewModel')]; + if (viewModel) { + return this.viewModel.apply(this, arguments); + } else { + return this.attribute.apply(this, arguments); + } + }, + scope: function (el, scope, scopeProp, bindingData, mustBeGettable, stickyCompute) { + if (!scopeProp) { + return new SimpleObservable(); + } else { + if (mustBeGettable || scopeProp.indexOf('(') >= 0 || scopeProp.indexOf('=') >= 0) { + var parentExpression = expression.parse(scopeProp, { baseMethodType: 'Call' }); + if (parentExpression instanceof expression.Hashes) { + return new SimpleObservable(function () { + var hashExprs = parentExpression.hashExprs; + var key = Object.keys(hashExprs)[0]; + var value = parentExpression.hashExprs[key].value(scope); + var isObservableValue = canReflect.isObservableLike(value) && canReflect.isValueLike(value); + scope.set(key, isObservableValue ? canReflect.getValue(value) : value); + }); + } else { + return parentExpression.value(scope); + } + } else { + var observation = {}; + canReflect.assignSymbols(observation, { + 'can.getValue': function getValue() { + }, + 'can.valueHasDependencies': function hasValueDependencies() { + return false; + }, + 'can.setValue': function setValue(newVal) { + var expr = expression.parse(cleanVMName(scopeProp, scope), { baseMethodType: 'Call' }); + var value = expr.value(scope); + canReflect.setValue(value, newVal); + }, + 'can.getWhatIChange': function getWhatIChange() { + var data = scope.getDataForScopeSet(cleanVMName(scopeProp, scope)); + var m = new Map(); + var s = new Set(); + s.add(data.key); + m.set(data.parent, s); + return { mutate: { keyDependencies: m } }; + }, + 'can.getName': function getName() { + } + }); + var data = scope.getDataForScopeSet(cleanVMName(scopeProp, scope)); + if (data.parent && data.key) { + canReflectDeps.addMutatedBy(data.parent, data.key, observation); + } + return observation; + } + } + }, + viewModel: function (el, scope, vmName, bindingData, mustBeGettable, stickyCompute, childEvent) { + var setName = cleanVMName(vmName, scope); + var isBoundToContext = vmName === '.' || vmName === 'this'; + var keysToRead = isBoundToContext ? [] : observeReader.reads(vmName); + function getViewModelProperty() { + var viewModel = bindingData.getViewModel(); + return observeReader.read(viewModel, keysToRead, {}).value; + } + var observation = new SettableObservable(getViewModelProperty, function setViewModelProperty(newVal) { + var viewModel = bindingData.getViewModel(); + if (stickyCompute) { + var oldValue = canReflect.getKeyValue(viewModel, setName); + if (canReflect.isObservableLike(oldValue)) { + canReflect.setValue(oldValue, newVal); + } else { + canReflect.setKeyValue(viewModel, setName, new SimpleObservable(canReflect.getValue(stickyCompute))); + } + } else { + if (isBoundToContext) { + canReflect.setValue(viewModel, newVal); + } else { + canReflect.setKeyValue(viewModel, setName, newVal); + } + } + }); + return observation; + }, + attribute: function (el, scope, prop, bindingData, mustBeGettable, stickyCompute, event, bindingInfo) { + return new AttributeObservable(el, prop, bindingData, event); + } + }; + var startsWith = String.prototype.startsWith || function (text) { + return this.indexOf(text) === 0; + }; + function getEventName(result) { + if (result.special.on !== undefined) { + return result.tokens[result.special.on + 1]; + } + } + var bindingRules = { + to: { + childToParent: true, + parentToChild: false, + syncChildWithParent: false + }, + from: { + childToParent: false, + parentToChild: true, + syncChildWithParent: false + }, + bind: { + childToParent: true, + parentToChild: true, + syncChildWithParent: true + }, + raw: { + childToParent: false, + parentToChild: true, + syncChildWithParent: false + } + }; + var bindingNames = []; + var special = { + vm: true, + on: true + }; + canReflect.each(bindingRules, function (value, key) { + bindingNames.push(key); + special[key] = true; + }); + function tokenize(source) { + var splitByColon = source.split(':'); + var result = { + tokens: [], + special: {} + }; + splitByColon.forEach(function (token) { + if (special[token]) { + result.special[token] = result.tokens.push(token) - 1; + } else { + result.tokens.push(token); + } + }); + return result; + } + var getChildBindingStr = function (tokens, favorViewModel) { + if (tokens.indexOf('vm') >= 0) { + return viewModelBindingStr; + } else if (tokens.indexOf('el') >= 0) { + return attributeBindingStr; + } else { + return favorViewModel ? viewModelBindingStr : viewModelOrAttributeBindingStr; + } + }; + var getBindingInfo = function (node, attributeViewModelBindings, templateType, tagName, favorViewModel) { + var bindingInfo, attributeName = encoder.decode(node.name), attributeValue = node.value || ''; + var result = tokenize(attributeName), dataBindingName, specialIndex; + bindingNames.forEach(function (name) { + if (result.special[name] !== undefined && result.special[name] > 0) { + dataBindingName = name; + specialIndex = result.special[name]; + return false; + } + }); + if (dataBindingName) { + var childEventName = getEventName(result); + var initializeValues = childEventName && dataBindingName !== 'bind' ? false : true; + bindingInfo = assign({ + parent: scopeBindingStr, + child: getChildBindingStr(result.tokens, favorViewModel), + childName: result.tokens[specialIndex - 1], + childEvent: childEventName, + bindingAttributeName: attributeName, + parentName: result.special.raw ? '"' + attributeValue + '"' : attributeValue, + initializeValues: initializeValues + }, bindingRules[dataBindingName]); + if (attributeValue.trim().charAt(0) === '~') { + bindingInfo.stickyParentToChild = true; + } + return bindingInfo; + } + }; + var makeDataBinding = function (node, el, bindingData) { + var bindingInfo = getBindingInfo(node, bindingData.attributeViewModelBindings, bindingData.templateType, el.nodeName.toLowerCase(), bindingData.favorViewModel); + if (!bindingInfo) { + return; + } + var parentObservable = getObservableFrom[bindingInfo.parent](el, bindingData.scope, bindingInfo.parentName, bindingData, bindingInfo.parentToChild, undefined, undefined, bindingInfo), childObservable = getObservableFrom[bindingInfo.child](el, bindingData.scope, bindingInfo.childName, bindingData, bindingInfo.childToParent, bindingInfo.stickyParentToChild && parentObservable, bindingInfo.childEvent, bindingInfo); + var childToParent = !!bindingInfo.childToParent; + var parentToChild = !!bindingInfo.parentToChild; + var bindingOptions = { + child: childObservable, + childToParent: childToParent, + cycles: childToParent === true && parentToChild === true ? 0 : 100, + onInitDoNotUpdateChild: bindingData.alreadyUpdatedChild, + onInitSetUndefinedParentIfChildIsDefined: true, + parent: parentObservable, + parentToChild: parentToChild, + priority: bindingData.nodeList ? bindingData.nodeList.nesting + 1 : undefined, + queue: 'domUI', + sticky: bindingInfo.syncChildWithParent ? 'childSticksToParent' : undefined + }; + var canBinding = new Bind(bindingOptions); + canBinding.startParent(); + return { + bindingInfo: bindingInfo, + canBinding: canBinding, + parent: parentObservable + }; + }; + var cleanVMName = function (name, scope) { + return name.replace(/@/g, ''); + }; + var canStacheBindings = { + behaviors: behaviors, + getBindingInfo: getBindingInfo, + bindings: bindings + }; + canStacheBindings[canSymbol.for('can.callbackMap')] = bindings; + viewCallbacks.attrs(canStacheBindings); + module.exports = canStacheBindings; +}); +/*can-simple-observable@2.4.1#async/async*/ +define('can-simple-observable@2.4.1#async/async', [ + 'require', + 'exports', + 'module', + '../can-simple-observable', + 'can-observation', + 'can-queues', + '../settable/settable', + 'can-reflect', + 'can-observation-recorder', + 'can-event-queue/value/value' +], function (require, exports, module) { + 'use strict'; + var SimpleObservable = require('../can-simple-observable'); + var Observation = require('can-observation'); + var queues = require('can-queues'); + var SettableObservable = require('../settable/settable'); + var canReflect = require('can-reflect'); + var ObservationRecorder = require('can-observation-recorder'); + var valueEventBindings = require('can-event-queue/value/value'); + function AsyncObservable(fn, context, initialValue) { + this.resolve = this.resolve.bind(this); + this.lastSetValue = new SimpleObservable(initialValue); + this.handler = this.handler.bind(this); + function observe() { + this.resolveCalled = false; + this.inGetter = true; + var newVal = fn.call(context, this.lastSetValue.get(), this.bound === true ? this.resolve : undefined); + this.inGetter = false; + if (newVal !== undefined) { + this.resolve(newVal); + } else if (this.resolveCalled) { + this.resolve(this._value); + } + if (this.bound !== true) { + return newVal; + } + } + this.observation = new Observation(observe, this); + } + AsyncObservable.prototype = Object.create(SettableObservable.prototype); + AsyncObservable.prototype.constructor = AsyncObservable; + AsyncObservable.prototype.handler = function (newVal) { + if (newVal !== undefined) { + SettableObservable.prototype.handler.apply(this, arguments); + } + }; + var peek = ObservationRecorder.ignore(canReflect.getValue.bind(canReflect)); + AsyncObservable.prototype.activate = function () { + canReflect.onValue(this.observation, this.handler, 'notify'); + if (!this.resolveCalled) { + this._value = peek(this.observation); + } + }; + AsyncObservable.prototype.resolve = function resolve(newVal) { + this.resolveCalled = true; + var old = this._value; + this._value = newVal; + if (!this.inGetter) { + var queuesArgs = [ + this.handlers.getNode([]), + this, + [ + newVal, + old + ], + null + ]; + queues.enqueueByQueue.apply(queues, queuesArgs); + } + }; + module.exports = AsyncObservable; +}); +/*can-simple-observable@2.4.1#resolver/resolver*/ +define('can-simple-observable@2.4.1#resolver/resolver', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-symbol', + 'can-observation-recorder', + 'can-observation', + 'can-queues', + 'can-event-queue/map/map', + '../settable/settable', + '../can-simple-observable' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var ObservationRecorder = require('can-observation-recorder'); + var Observation = require('can-observation'); + var queues = require('can-queues'); + var mapEventBindings = require('can-event-queue/map/map'); + var SettableObservable = require('../settable/settable'); + var SimpleObservable = require('../can-simple-observable'); + var getChangesSymbol = canSymbol.for('can.getChangesDependencyRecord'); + function ResolverObservable(resolver, context, initialValue) { + this.resolver = ObservationRecorder.ignore(resolver); + this.context = context; + this._valueOptions = { + resolve: this.resolve.bind(this), + listenTo: this.listenTo.bind(this), + stopListening: this.stopListening.bind(this), + lastSet: new SimpleObservable(initialValue) + }; + this.update = this.update.bind(this); + this.contextHandlers = new WeakMap(); + this.teardown = null; + this.binder = {}; + } + ResolverObservable.prototype = Object.create(SettableObservable.prototype); + function deleteHandler(bindTarget, event, queue, handler) { + mapEventBindings.off.call(bindTarget, event, handler, queue); + } + canReflect.assignMap(ResolverObservable.prototype, { + constructor: ResolverObservable, + listenTo: function (bindTarget, event, handler, queueName) { + if (canReflect.isPrimitive(bindTarget)) { + handler = event; + event = bindTarget; + bindTarget = this.context; + } + if (typeof event === 'function') { + handler = event; + event = undefined; + } + var resolverInstance = this; + var contextHandler = handler.bind(this.context); + contextHandler[getChangesSymbol] = function getChangesDependencyRecord() { + var s = new Set(); + s.add(resolverInstance); + return { valueDependencies: s }; + }; + this.contextHandlers.set(handler, contextHandler); + mapEventBindings.listenTo.call(this.binder, bindTarget, event, contextHandler, queueName || 'notify'); + }, + stopListening: function () { + var meta = this.binder[canSymbol.for('can.meta')]; + var listenHandlers = meta && meta.listenHandlers; + if (listenHandlers) { + var keys = mapEventBindings.stopListeningArgumentsToKeys.call({ + context: this.context, + defaultQueue: 'notify' + }); + listenHandlers.delete(keys, deleteHandler); + } + return this; + }, + resolve: function (newVal) { + this._value = newVal; + if (this.isBinding) { + this.lastValue = this._value; + return newVal; + } + if (this._value !== this.lastValue) { + var enqueueMeta = {}; + queues.batch.start(); + queues.deriveQueue.enqueue(this.update, this, [], enqueueMeta); + queues.batch.stop(); + } + return newVal; + }, + update: function () { + if (this.lastValue !== this._value) { + var old = this.lastValue; + this.lastValue = this._value; + queues.enqueueByQueue(this.handlers.getNode([]), this, [ + this._value, + old + ]); + } + }, + activate: function () { + this.isBinding = true; + this.teardown = this.resolver.call(this.context, this._valueOptions); + this.isBinding = false; + }, + onUnbound: function () { + this.bound = false; + mapEventBindings.stopListening.call(this.binder); + if (this.teardown != null) { + this.teardown(); + this.teardown = null; + } + }, + set: function (value) { + this._valueOptions.lastSet.set(value); + }, + get: function () { + if (ObservationRecorder.isRecording()) { + ObservationRecorder.add(this); + if (!this.bound) { + this.onBound(); + } + } + if (this.bound === true) { + return this._value; + } else { + var handler = function () { + }; + this.on(handler); + var val = this._value; + this.off(handler); + return val; + } + }, + hasDependencies: function hasDependencies() { + var hasDependencies = false; + if (this.bound) { + var meta = this.binder[canSymbol.for('can.meta')]; + var listenHandlers = meta && meta.listenHandlers; + hasDependencies = !!listenHandlers.size(); + } + return hasDependencies; + }, + getValueDependencies: function getValueDependencies() { + if (this.bound) { + var meta = this.binder[canSymbol.for('can.meta')]; + var listenHandlers = meta && meta.listenHandlers; + var keyDeps = new Map(); + var valueDeps = new Set(); + if (listenHandlers) { + canReflect.each(listenHandlers.root, function (events, obj) { + canReflect.each(events, function (queues, eventName) { + if (eventName === undefined) { + valueDeps.add(obj); + } else { + var entry = keyDeps.get(obj); + if (!entry) { + entry = new Set(); + keyDeps.set(obj, entry); + } + entry.add(eventName); + } + }); + }); + if (valueDeps.size || keyDeps.size) { + var result = {}; + if (keyDeps.size) { + result.keyDependencies = keyDeps; + } + if (valueDeps.size) { + result.valueDependencies = valueDeps; + } + return result; + } + } + } + } + }); + canReflect.assignSymbols(ResolverObservable.prototype, { + 'can.getValue': ResolverObservable.prototype.get, + 'can.setValue': ResolverObservable.prototype.set, + 'can.isMapLike': false, + 'can.getPriority': function () { + return this.priority || 0; + }, + 'can.setPriority': function (newPriority) { + this.priority = newPriority; + }, + 'can.valueHasDependencies': ResolverObservable.prototype.hasDependencies, + 'can.getValueDependencies': ResolverObservable.prototype.getValueDependencies + }); + module.exports = ResolverObservable; +}); +/*can-event-queue@1.1.3#type/type*/ +define('can-event-queue@1.1.3#type/type', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-symbol', + 'can-key-tree', + 'can-queues' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var KeyTree = require('can-key-tree'); + var queues = require('can-queues'); + var metaSymbol = canSymbol.for('can.meta'); + function addHandlers(obj, meta) { + if (!meta.lifecycleHandlers) { + meta.lifecycleHandlers = new KeyTree([ + Object, + Array + ]); + } + if (!meta.instancePatchesHandlers) { + meta.instancePatchesHandlers = new KeyTree([ + Object, + Array + ]); + } + } + function ensureMeta(obj) { + var meta = obj[metaSymbol]; + if (!meta) { + meta = {}; + canReflect.setKeyValue(obj, metaSymbol, meta); + } + addHandlers(obj, meta); + return meta; + } + var props = {}; + function onOffAndDispatch(symbolName, dispatchName, handlersName) { + props['can.on' + symbolName] = function (handler, queueName) { + ensureMeta(this)[handlersName].add([ + queueName || 'mutate', + handler + ]); + }; + props['can.off' + symbolName] = function (handler, queueName) { + ensureMeta(this)[handlersName].delete([ + queueName || 'mutate', + handler + ]); + }; + props['can.' + dispatchName] = function (instance, arg) { + queues.enqueueByQueue(ensureMeta(this)[handlersName].getNode([]), this, [ + instance, + arg + ]); + }; + } + onOffAndDispatch('InstancePatches', 'dispatchInstanceOnPatches', 'instancePatchesHandlers'); + onOffAndDispatch('InstanceBoundChange', 'dispatchInstanceBoundChange', 'lifecycleHandlers'); + function mixinTypeBindings(obj) { + return canReflect.assignSymbols(obj, props); + } + Object.defineProperty(mixinTypeBindings, 'addHandlers', { + enumerable: false, + value: addHandlers + }); + module.exports = mixinTypeBindings; +}); +/*can-string-to-any@1.2.0#can-string-to-any*/ +define('can-string-to-any@1.2.0#can-string-to-any', function (require, exports, module) { + 'use strict'; + module.exports = function (str) { + switch (str) { + case 'NaN': + case 'Infinity': + return +str; + case 'null': + return null; + case 'undefined': + return undefined; + case 'true': + case 'false': + return str === 'true'; + default: + var val = +str; + if (!isNaN(val)) { + return val; + } else { + return str; + } + } + }; +}); +/*can-data-types@1.2.0#maybe-boolean/maybe-boolean*/ +define('can-data-types@1.2.0#maybe-boolean/maybe-boolean', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + function toBoolean(val) { + if (val == null) { + return val; + } + if (val === 'false' || val === '0' || !val) { + return false; + } + return true; + } + module.exports = canReflect.assignSymbols(toBoolean, { + 'can.new': toBoolean, + 'can.getSchema': function () { + return { + type: 'Or', + values: [ + true, + false, + undefined, + null + ] + }; + }, + 'can.getName': function () { + return 'MaybeBoolean'; + }, + 'can.isMember': function (value) { + return value == null || typeof value === 'boolean'; + } + }); +}); +/*can-data-types@1.2.0#maybe-date/maybe-date*/ +define('can-data-types@1.2.0#maybe-date/maybe-date', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + function toDate(str) { + var type = typeof str; + if (type === 'string') { + str = Date.parse(str); + return isNaN(str) ? null : new Date(str); + } else if (type === 'number') { + return new Date(str); + } else { + return str; + } + } + function DateStringSet(dateStr) { + this.setValue = dateStr; + var date = toDate(dateStr); + this.value = date == null ? date : date.getTime(); + } + DateStringSet.prototype.valueOf = function () { + return this.value; + }; + canReflect.assignSymbols(DateStringSet.prototype, { + 'can.serialize': function () { + return this.setValue; + } + }); + module.exports = canReflect.assignSymbols(toDate, { + 'can.new': toDate, + 'can.getSchema': function () { + return { + type: 'Or', + values: [ + Date, + undefined, + null + ] + }; + }, + 'can.ComparisonSetType': DateStringSet, + 'can.getName': function () { + return 'MaybeDate'; + }, + 'can.isMember': function (value) { + return value == null || value instanceof Date; + } + }); +}); +/*can-data-types@1.2.0#maybe-number/maybe-number*/ +define('can-data-types@1.2.0#maybe-number/maybe-number', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + function toNumber(val) { + if (val == null) { + return val; + } + return +val; + } + module.exports = canReflect.assignSymbols(toNumber, { + 'can.new': toNumber, + 'can.getSchema': function () { + return { + type: 'Or', + values: [ + Number, + undefined, + null + ] + }; + }, + 'can.getName': function () { + return 'MaybeNumber'; + }, + 'can.isMember': function (value) { + return value == null || typeof value === 'number'; + } + }); +}); +/*can-data-types@1.2.0#maybe-string/maybe-string*/ +define('can-data-types@1.2.0#maybe-string/maybe-string', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + function toString(val) { + if (val == null) { + return val; + } + return '' + val; + } + module.exports = canReflect.assignSymbols(toString, { + 'can.new': toString, + 'can.getSchema': function () { + return { + type: 'Or', + values: [ + String, + undefined, + null + ] + }; + }, + 'can.getName': function () { + return 'MaybeString'; + }, + 'can.isMember': function (value) { + return value == null || typeof value === 'string'; + } + }); +}); +/*can-define@2.7.1#can-define*/ +define('can-define@2.7.1#can-define', [ + 'require', + 'exports', + 'module', + 'can-namespace', + 'can-symbol', + 'can-reflect', + 'can-observation', + 'can-observation-recorder', + 'can-simple-observable/async/async', + 'can-simple-observable/settable/settable', + 'can-simple-observable/resolver/resolver', + 'can-event-queue/map/map', + 'can-event-queue/type/type', + 'can-queues', + 'can-assign', + 'can-log/dev/dev', + 'can-string-to-any', + 'can-define-lazy-value', + 'can-data-types/maybe-boolean/maybe-boolean', + 'can-data-types/maybe-date/maybe-date', + 'can-data-types/maybe-number/maybe-number', + 'can-data-types/maybe-string/maybe-string' +], function (require, exports, module) { + 'use strict'; + 'format cjs'; + var ns = require('can-namespace'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + var Observation = require('can-observation'); + var ObservationRecorder = require('can-observation-recorder'); + var AsyncObservable = require('can-simple-observable/async/async'); + var SettableObservable = require('can-simple-observable/settable/settable'); + var ResolverObservable = require('can-simple-observable/resolver/resolver'); + var eventQueue = require('can-event-queue/map/map'); + var addTypeEvents = require('can-event-queue/type/type'); + var queues = require('can-queues'); + var assign = require('can-assign'); + var canLogDev = require('can-log/dev/dev'); + var stringToAny = require('can-string-to-any'); + var defineLazyValue = require('can-define-lazy-value'); + var MaybeBoolean = require('can-data-types/maybe-boolean/maybe-boolean'), MaybeDate = require('can-data-types/maybe-date/maybe-date'), MaybeNumber = require('can-data-types/maybe-number/maybe-number'), MaybeString = require('can-data-types/maybe-string/maybe-string'); + var newSymbol = canSymbol.for('can.new'), serializeSymbol = canSymbol.for('can.serialize'); + var eventsProto, define, make, makeDefinition, getDefinitionsAndMethods, getDefinitionOrMethod; + function isDefineType(func) { + return func && (func.canDefineType === true || func[newSymbol]); + } + var peek = ObservationRecorder.ignore(canReflect.getValue.bind(canReflect)); + var Object_defineNamedPrototypeProperty = Object.defineProperty; + function defineConfigurableAndNotEnumerable(obj, prop, value) { + Object.defineProperty(obj, prop, { + configurable: true, + enumerable: false, + writable: true, + value: value + }); + } + function eachPropertyDescriptor(map, cb) { + for (var prop in map) { + if (map.hasOwnProperty(prop)) { + cb.call(map, prop, Object.getOwnPropertyDescriptor(map, prop)); + } + } + } + function getEveryPropertyAndSymbol(obj) { + var props = Object.getOwnPropertyNames(obj); + var symbols = 'getOwnPropertySymbols' in Object ? Object.getOwnPropertySymbols(obj) : []; + return props.concat(symbols); + } + function cleanUpDefinition(prop, definition, shouldWarn, typePrototype) { + if (definition.value !== undefined && (typeof definition.value !== 'function' || definition.value.length === 0)) { + definition.default = definition.value; + delete definition.value; + } + if (definition.Value !== undefined) { + definition.Default = definition.Value; + delete definition.Value; + } + } + function isValueResolver(definition) { + return typeof definition.value === 'function' && definition.value.length; + } + module.exports = define = ns.define = function (typePrototype, defines, baseDefine) { + var prop, dataInitializers = Object.create(baseDefine ? baseDefine.dataInitializers : null), computedInitializers = Object.create(baseDefine ? baseDefine.computedInitializers : null); + var result = getDefinitionsAndMethods(defines, baseDefine, typePrototype); + result.dataInitializers = dataInitializers; + result.computedInitializers = computedInitializers; + canReflect.eachKey(result.definitions, function (definition, property) { + define.property(typePrototype, property, definition, dataInitializers, computedInitializers, result.defaultDefinition); + }); + if (typePrototype.hasOwnProperty('_data')) { + for (prop in dataInitializers) { + defineLazyValue(typePrototype._data, prop, dataInitializers[prop].bind(typePrototype), true); + } + } else { + defineLazyValue(typePrototype, '_data', function () { + var map = this; + var data = {}; + for (var prop in dataInitializers) { + defineLazyValue(data, prop, dataInitializers[prop].bind(map), true); + } + return data; + }); + } + if (typePrototype.hasOwnProperty('_computed')) { + for (prop in computedInitializers) { + defineLazyValue(typePrototype._computed, prop, computedInitializers[prop].bind(typePrototype)); + } + } else { + defineLazyValue(typePrototype, '_computed', function () { + var map = this; + var data = Object.create(null); + for (var prop in computedInitializers) { + defineLazyValue(data, prop, computedInitializers[prop].bind(map)); + } + return data; + }); + } + getEveryPropertyAndSymbol(eventsProto).forEach(function (prop) { + Object.defineProperty(typePrototype, prop, { + enumerable: false, + value: eventsProto[prop], + configurable: true, + writable: true + }); + }); + Object.defineProperty(typePrototype, '_define', { + enumerable: false, + value: result, + configurable: true, + writable: true + }); + var iteratorSymbol = canSymbol.iterator || canSymbol.for('iterator'); + if (!typePrototype[iteratorSymbol]) { + defineConfigurableAndNotEnumerable(typePrototype, iteratorSymbol, function () { + return new define.Iterator(this); + }); + } + return result; + }; + var onlyType = function (obj) { + for (var prop in obj) { + if (prop !== 'type') { + return false; + } + } + return true; + }; + define.extensions = function () { + }; + define.property = function (typePrototype, prop, definition, dataInitializers, computedInitializers, defaultDefinition) { + var propertyDefinition = define.extensions.apply(this, arguments); + if (propertyDefinition) { + definition = makeDefinition(prop, propertyDefinition, defaultDefinition || {}, typePrototype); + } + var type = definition.type; + if (type && onlyType(definition) && type === define.types['*']) { + Object_defineNamedPrototypeProperty(typePrototype, prop, { + get: make.get.data(prop), + set: make.set.events(prop, make.get.data(prop), make.set.data(prop), make.eventType.data(prop)), + enumerable: true, + configurable: true + }); + return; + } + definition.type = type; + var dataProperty = definition.get || isValueResolver(definition) ? 'computed' : 'data', reader = make.read[dataProperty](prop), getter = make.get[dataProperty](prop), setter = make.set[dataProperty](prop), getInitialValue; + var typeConvert = function (val) { + return val; + }; + if (definition.Type) { + typeConvert = make.set.Type(prop, definition.Type, typeConvert); + } + if (type) { + typeConvert = make.set.type(prop, type, typeConvert); + } + var eventsSetter = make.set.events(prop, reader, setter, make.eventType[dataProperty](prop)); + if (isValueResolver(definition)) { + computedInitializers[prop] = make.valueResolver(prop, definition, typeConvert); + } else if (definition.default !== undefined || definition.Default !== undefined) { + getInitialValue = ObservationRecorder.ignore(make.get.defaultValue(prop, definition, typeConvert, eventsSetter)); + } + if (definition.get) { + computedInitializers[prop] = make.compute(prop, definition.get, getInitialValue); + } else if (getInitialValue) { + dataInitializers[prop] = getInitialValue; + } + if (definition.get && definition.set) { + setter = make.set.setter(prop, definition.set, make.read.lastSet(prop), setter, true); + } else if (definition.set) { + setter = make.set.setter(prop, definition.set, reader, eventsSetter, false); + } else if (dataProperty === 'data') { + setter = eventsSetter; + } else if (definition.get && definition.get.length < 1) { + setter = function () { + }; + } + if (type) { + setter = make.set.type(prop, type, setter); + } + if (definition.Type) { + setter = make.set.Type(prop, definition.Type, setter); + } + Object_defineNamedPrototypeProperty(typePrototype, prop, { + get: getter, + set: setter, + enumerable: 'serialize' in definition ? !!definition.serialize : !definition.get, + configurable: true + }); + }; + define.makeDefineInstanceKey = function (constructor) { + constructor[canSymbol.for('can.defineInstanceKey')] = function (property, value) { + var defineResult = this.prototype._define; + if (typeof value === 'object') { + cleanUpDefinition(property, value, false, this); + } + var definition = getDefinitionOrMethod(property, value, defineResult.defaultDefinition, this); + if (definition && typeof definition === 'object') { + define.property(constructor.prototype, property, definition, defineResult.dataInitializers, defineResult.computedInitializers, defineResult.defaultDefinition); + defineResult.definitions[property] = definition; + } else { + defineResult.methods[property] = definition; + } + this.prototype.dispatch({ + type: 'can.keys', + target: this.prototype + }); + }; + }; + define.Constructor = function (defines, sealed) { + var constructor = function DefineConstructor(props) { + Object.defineProperty(this, '__inSetup', { + configurable: true, + enumerable: false, + value: true, + writable: true + }); + define.setup.call(this, props, sealed); + this.__inSetup = false; + }; + var result = define(constructor.prototype, defines); + addTypeEvents(constructor); + define.makeDefineInstanceKey(constructor, result); + return constructor; + }; + make = { + computeObj: function (map, prop, observable) { + var computeObj = { + oldValue: undefined, + compute: observable, + count: 0, + handler: function (newVal) { + var oldValue = computeObj.oldValue; + computeObj.oldValue = newVal; + map.dispatch({ + type: prop, + target: map + }, [ + newVal, + oldValue + ]); + } + }; + return computeObj; + }, + valueResolver: function (prop, definition, typeConvert) { + var getDefault = make.get.defaultValue(prop, definition, typeConvert); + return function () { + var map = this; + var defaultValue = getDefault.call(this); + var computeObj = make.computeObj(map, prop, new ResolverObservable(definition.value, map, defaultValue)); + return computeObj; + }; + }, + compute: function (prop, get, defaultValueFn) { + return function () { + var map = this, defaultValue = defaultValueFn && defaultValueFn.call(this), observable, computeObj; + if (get.length === 0) { + observable = new Observation(get, map); + } else if (get.length === 1) { + observable = new SettableObservable(get, map, defaultValue); + } else { + observable = new AsyncObservable(get, map, defaultValue); + } + computeObj = make.computeObj(map, prop, observable); + return computeObj; + }; + }, + set: { + data: function (prop) { + return function (newVal) { + this._data[prop] = newVal; + }; + }, + computed: function (prop) { + return function (val) { + canReflect.setValue(this._computed[prop].compute, val); + }; + }, + events: function (prop, getCurrent, setData, eventType) { + return function (newVal) { + if (this.__inSetup) { + setData.call(this, newVal); + } else { + var current = getCurrent.call(this); + if (newVal !== current) { + var dispatched; + setData.call(this, newVal); + dispatched = { + patches: [{ + type: 'set', + key: prop, + value: newVal + }], + type: prop, + target: this + }; + this.dispatch(dispatched, [ + newVal, + current + ]); + } + } + }; + }, + setter: function (prop, setter, getCurrent, setEvents, hasGetter) { + return function (value) { + var self = this; + queues.batch.start(); + var setterCalled = false, current = getCurrent.call(this), setValue = setter.call(this, value, function (value) { + setEvents.call(self, value); + setterCalled = true; + }, current); + if (setterCalled) { + queues.batch.stop(); + } else { + if (hasGetter) { + if (setValue !== undefined) { + if (current !== setValue) { + setEvents.call(this, setValue); + } + queues.batch.stop(); + } else if (setter.length === 0) { + setEvents.call(this, value); + queues.batch.stop(); + return; + } else if (setter.length === 1) { + queues.batch.stop(); + } else { + queues.batch.stop(); + return; + } + } else { + if (setValue !== undefined) { + setEvents.call(this, setValue); + queues.batch.stop(); + } else if (setter.length === 0) { + setEvents.call(this, value); + queues.batch.stop(); + return; + } else if (setter.length === 1) { + setEvents.call(this, undefined); + queues.batch.stop(); + } else { + queues.batch.stop(); + return; + } + } + } + }; + }, + type: function (prop, type, set) { + function setter(newValue) { + return set.call(this, type.call(this, newValue, prop)); + } + if (isDefineType(type)) { + if (type.canDefineType) { + return setter; + } else { + return function setter(newValue) { + return set.call(this, canReflect.convert(newValue, type)); + }; + } + } + if (typeof type === 'object') { + return make.set.Type(prop, type, set); + } else { + return setter; + } + }, + Type: function (prop, Type, set) { + if (Array.isArray(Type) && define.DefineList) { + Type = define.DefineList.extend({ '#': Type[0] }); + } else if (typeof Type === 'object') { + if (define.DefineMap) { + Type = define.DefineMap.extend(Type); + } else { + Type = define.Constructor(Type); + } + } + return function (newValue) { + if (newValue instanceof Type || newValue == null) { + return set.call(this, newValue); + } else { + return set.call(this, new Type(newValue)); + } + }; + } + }, + eventType: { + data: function (prop) { + return function (newVal, oldVal) { + return oldVal !== undefined || this._data.hasOwnProperty(prop) ? 'set' : 'add'; + }; + }, + computed: function () { + return function () { + return 'set'; + }; + } + }, + read: { + data: function (prop) { + return function () { + return this._data[prop]; + }; + }, + computed: function (prop) { + return function () { + return canReflect.getValue(this._computed[prop].compute); + }; + }, + lastSet: function (prop) { + return function () { + var observable = this._computed[prop].compute; + if (observable.lastSetValue) { + return canReflect.getValue(observable.lastSetValue); + } + }; + } + }, + get: { + defaultValue: function (prop, definition, typeConvert, callSetter) { + return function () { + var value = definition.default; + if (value !== undefined) { + if (typeof value === 'function') { + value = value.call(this); + } + value = typeConvert.call(this, value); + } else { + var Default = definition.Default; + if (Default) { + value = typeConvert.call(this, new Default()); + } + } + if (definition.set) { + var VALUE; + var sync = true; + var setter = make.set.setter(prop, definition.set, function () { + }, function (value) { + if (sync) { + VALUE = value; + } else { + callSetter.call(this, value); + } + }, definition.get); + setter.call(this, value); + sync = false; + return VALUE; + } + return value; + }; + }, + data: function (prop) { + return function () { + if (!this.__inSetup) { + ObservationRecorder.add(this, prop); + } + return this._data[prop]; + }; + }, + computed: function (prop) { + return function (val) { + var compute = this._computed[prop].compute; + if (ObservationRecorder.isRecording()) { + ObservationRecorder.add(this, prop); + if (!canReflect.isBound(compute)) { + Observation.temporarilyBind(compute); + } + } + return peek(compute); + }; + } + } + }; + define.behaviors = [ + 'get', + 'set', + 'value', + 'Value', + 'type', + 'Type', + 'serialize' + ]; + var addBehaviorToDefinition = function (definition, behavior, value) { + if (behavior === 'enumerable') { + definition.serialize = !!value; + } else if (behavior === 'type') { + var behaviorDef = value; + if (typeof behaviorDef === 'string') { + behaviorDef = define.types[behaviorDef]; + if (typeof behaviorDef === 'object' && !isDefineType(behaviorDef)) { + assign(definition, behaviorDef); + behaviorDef = behaviorDef[behavior]; + } + } + if (typeof behaviorDef !== 'undefined') { + definition[behavior] = behaviorDef; + } + } else { + definition[behavior] = value; + } + }; + makeDefinition = function (prop, def, defaultDefinition, typePrototype) { + var definition = {}; + canReflect.eachKey(def, function (value, behavior) { + addBehaviorToDefinition(definition, behavior, value); + }); + canReflect.eachKey(defaultDefinition, function (value, prop) { + if (definition[prop] === undefined) { + if (prop !== 'type' && prop !== 'Type') { + definition[prop] = value; + } + } + }); + if (def.Type) { + var value = def.Type; + var serialize = value[serializeSymbol]; + if (serialize) { + definition.serialize = function (val) { + return serialize.call(val); + }; + } + if (value[newSymbol]) { + definition.type = value[newSymbol]; + delete definition.Type; + } + } + if (typeof def.type !== 'string') { + if (!definition.type && !definition.Type) { + var defaultsCopy = canReflect.assignMap({}, defaultDefinition); + definition = canReflect.assignMap(defaultsCopy, definition); + } + if (canReflect.size(definition) === 0) { + definition.type = define.types['*']; + } + } + cleanUpDefinition(prop, definition, true, typePrototype); + return definition; + }; + getDefinitionOrMethod = function (prop, value, defaultDefinition, typePrototype) { + var definition; + if (typeof value === 'string') { + definition = { type: value }; + } else if (value && (value[serializeSymbol] || value[newSymbol])) { + definition = { Type: value }; + } else if (typeof value === 'function') { + if (canReflect.isConstructorLike(value)) { + definition = { Type: value }; + } + } else if (Array.isArray(value)) { + definition = { Type: value }; + } else if (canReflect.isPlainObject(value)) { + definition = value; + } + if (definition) { + return makeDefinition(prop, definition, defaultDefinition, typePrototype); + } else { + return value; + } + }; + getDefinitionsAndMethods = function (defines, baseDefines, typePrototype) { + var definitions = Object.create(baseDefines ? baseDefines.definitions : null); + var methods = {}; + var defaults = defines['*'], defaultDefinition; + if (defaults) { + delete defines['*']; + defaultDefinition = getDefinitionOrMethod('*', defaults, {}); + } else { + defaultDefinition = Object.create(null); + } + eachPropertyDescriptor(defines, function (prop, propertyDescriptor) { + var value; + if (propertyDescriptor.get || propertyDescriptor.set) { + value = { + get: propertyDescriptor.get, + set: propertyDescriptor.set + }; + } else { + value = propertyDescriptor.value; + } + if (prop === 'constructor') { + methods[prop] = value; + return; + } else { + var result = getDefinitionOrMethod(prop, value, defaultDefinition, typePrototype); + if (result && typeof result === 'object' && canReflect.size(result) > 0) { + definitions[prop] = result; + } else { + if (typeof result === 'function') { + methods[prop] = result; + } + } + } + }); + if (defaults) { + defineConfigurableAndNotEnumerable(defines, '*', defaults); + } + return { + definitions: definitions, + methods: methods, + defaultDefinition: defaultDefinition + }; + }; + eventsProto = eventQueue({}); + function setupComputed(instance, eventName) { + var computedBinding = instance._computed && instance._computed[eventName]; + if (computedBinding && computedBinding.compute) { + if (!computedBinding.count) { + computedBinding.count = 1; + canReflect.onValue(computedBinding.compute, computedBinding.handler, 'notify'); + computedBinding.oldValue = peek(computedBinding.compute); + } else { + computedBinding.count++; + } + } + } + function teardownComputed(instance, eventName) { + var computedBinding = instance._computed && instance._computed[eventName]; + if (computedBinding) { + if (computedBinding.count === 1) { + computedBinding.count = 0; + canReflect.offValue(computedBinding.compute, computedBinding.handler, 'notify'); + } else { + computedBinding.count--; + } + } + } + var canMetaSymbol = canSymbol.for('can.meta'); + assign(eventsProto, { + _eventSetup: function () { + }, + _eventTeardown: function () { + }, + addEventListener: function (eventName, handler, queue) { + setupComputed(this, eventName); + return eventQueue.addEventListener.apply(this, arguments); + }, + removeEventListener: function (eventName, handler) { + teardownComputed(this, eventName); + return eventQueue.removeEventListener.apply(this, arguments); + } + }); + eventsProto.on = eventsProto.bind = eventsProto.addEventListener; + eventsProto.off = eventsProto.unbind = eventsProto.removeEventListener; + var onKeyValueSymbol = canSymbol.for('can.onKeyValue'); + var offKeyValueSymbol = canSymbol.for('can.offKeyValue'); + canReflect.assignSymbols(eventsProto, { + 'can.onKeyValue': function (key) { + setupComputed(this, key); + return eventQueue[onKeyValueSymbol].apply(this, arguments); + }, + 'can.offKeyValue': function (key) { + teardownComputed(this, key); + return eventQueue[offKeyValueSymbol].apply(this, arguments); + } + }); + delete eventsProto.one; + define.setup = function (props, sealed) { + Object.defineProperty(this, 'constructor', { + value: this.constructor, + enumerable: false, + writable: false + }); + Object.defineProperty(this, canMetaSymbol, { + value: Object.create(null), + enumerable: false, + writable: false + }); + var definitions = this._define.definitions; + var instanceDefinitions = Object.create(null); + var map = this; + canReflect.eachKey(props, function (value, prop) { + if (definitions[prop] !== undefined) { + map[prop] = value; + } else { + define.expando(map, prop, value); + } + }); + if (canReflect.size(instanceDefinitions) > 0) { + defineConfigurableAndNotEnumerable(this, '_instanceDefinitions', instanceDefinitions); + } + }; + var returnFirstArg = function (arg) { + return arg; + }; + define.expando = function (map, prop, value) { + if (define._specialKeys[prop]) { + return true; + } + var constructorDefines = map._define.definitions; + if (constructorDefines && constructorDefines[prop]) { + return; + } + var instanceDefines = map._instanceDefinitions; + if (!instanceDefines) { + if (Object.isSealed(map)) { + return; + } + Object.defineProperty(map, '_instanceDefinitions', { + configurable: true, + enumerable: false, + writable: true, + value: {} + }); + instanceDefines = map._instanceDefinitions; + } + if (!instanceDefines[prop]) { + var defaultDefinition = map._define.defaultDefinition || { type: define.types.observable }; + define.property(map, prop, defaultDefinition, {}, {}); + if (defaultDefinition.type) { + map._data[prop] = define.make.set.type(prop, defaultDefinition.type, returnFirstArg).call(map, value); + } else { + map._data[prop] = define.types.observable(value); + } + instanceDefines[prop] = defaultDefinition; + if (!map.__inSetup) { + queues.batch.start(); + map.dispatch({ + type: 'can.keys', + target: map + }); + if (map._data[prop] !== undefined) { + map.dispatch({ + type: prop, + target: map, + patches: [{ + type: 'set', + key: prop, + value: map._data[prop] + }] + }, [ + map._data[prop], + undefined + ]); + } + queues.batch.stop(); + } + return true; + } + }; + define.replaceWith = defineLazyValue; + define.eventsProto = eventsProto; + define.defineConfigurableAndNotEnumerable = defineConfigurableAndNotEnumerable; + define.make = make; + define.getDefinitionOrMethod = getDefinitionOrMethod; + define._specialKeys = { + _data: true, + _computed: true + }; + var simpleGetterSetters = {}; + define.makeSimpleGetterSetter = function (prop) { + if (simpleGetterSetters[prop] === undefined) { + var setter = make.set.events(prop, make.get.data(prop), make.set.data(prop), make.eventType.data(prop)); + simpleGetterSetters[prop] = { + get: make.get.data(prop), + set: function (newVal) { + return setter.call(this, define.types.observable(newVal)); + }, + enumerable: true, + configurable: true + }; + } + return simpleGetterSetters[prop]; + }; + define.Iterator = function (obj) { + this.obj = obj; + this.definitions = Object.keys(obj._define.definitions); + this.instanceDefinitions = obj._instanceDefinitions ? Object.keys(obj._instanceDefinitions) : Object.keys(obj); + this.hasGet = typeof obj.get === 'function'; + }; + define.Iterator.prototype.next = function () { + var key; + if (this.definitions.length) { + key = this.definitions.shift(); + var def = this.obj._define.definitions[key]; + if (def.get) { + return this.next(); + } + } else if (this.instanceDefinitions.length) { + key = this.instanceDefinitions.shift(); + } else { + return { + value: undefined, + done: true + }; + } + return { + value: [ + key, + this.hasGet ? this.obj.get(key) : this.obj[key] + ], + done: false + }; + }; + function isObservableValue(obj) { + return canReflect.isValueLike(obj) && canReflect.isObservableLike(obj); + } + define.types = { + 'date': MaybeDate, + 'number': MaybeNumber, + 'boolean': MaybeBoolean, + 'observable': function (newVal) { + if (Array.isArray(newVal) && define.DefineList) { + newVal = new define.DefineList(newVal); + } else if (canReflect.isPlainObject(newVal) && define.DefineMap) { + newVal = new define.DefineMap(newVal); + } + return newVal; + }, + 'stringOrObservable': function (newVal) { + if (Array.isArray(newVal)) { + return new define.DefaultList(newVal); + } else if (canReflect.isPlainObject(newVal)) { + return new define.DefaultMap(newVal); + } else { + return canReflect.convert(newVal, define.types.string); + } + }, + 'htmlbool': function (val) { + if (val === '') { + return true; + } + return !!stringToAny(val); + }, + '*': function (val) { + return val; + }, + 'any': function (val) { + return val; + }, + 'string': MaybeString, + 'compute': { + set: function (newValue, setVal, setErr, oldValue) { + if (isObservableValue(newValue)) { + return newValue; + } + if (isObservableValue(oldValue)) { + canReflect.setValue(oldValue, newValue); + return oldValue; + } + return newValue; + }, + get: function (value) { + return isObservableValue(value) ? canReflect.getValue(value) : value; + } + } + }; + define.updateSchemaKeys = function (schema, definitions) { + for (var prop in definitions) { + var definition = definitions[prop]; + if (definition.serialize !== false) { + if (definition.type) { + schema.keys[prop] = definition.type; + } else { + schema.keys[prop] = function (val) { + return val; + }; + } + if (definitions[prop].identity === true) { + schema.identity.push(prop); + } + } + } + return schema; + }; +}); +/*can-define@2.7.1#ensure-meta*/ +define('can-define@2.7.1#ensure-meta', [ + 'require', + 'exports', + 'module', + 'can-symbol', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + module.exports = function ensureMeta(obj) { + var metaSymbol = canSymbol.for('can.meta'); + var meta = obj[metaSymbol]; + if (!meta) { + meta = {}; + canReflect.setKeyValue(obj, metaSymbol, meta); + } + return meta; + }; +}); +/*can-define@2.7.1#define-helpers/define-helpers*/ +define('can-define@2.7.1#define-helpers/define-helpers', [ + 'require', + 'exports', + 'module', + 'can-define', + 'can-reflect', + 'can-queues', + 'can-log/dev/dev', + '../ensure-meta' +], function (require, exports, module) { + 'use strict'; + var define = require('can-define'); + var canReflect = require('can-reflect'); + var queues = require('can-queues'); + var dev = require('can-log/dev/dev'); + var ensureMeta = require('../ensure-meta'); + var defineHelpers = { + defineExpando: define.expando, + reflectSerialize: function (unwrapped) { + var constructorDefinitions = this._define.definitions; + var defaultDefinition = this._define.defaultDefinition; + this.forEach(function (val, name) { + var propDef = constructorDefinitions[name]; + if (propDef && typeof propDef.serialize === 'function') { + val = propDef.serialize.call(this, val, name); + } else if (defaultDefinition && typeof defaultDefinition.serialize === 'function') { + val = defaultDefinition.serialize.call(this, val, name); + } else { + val = canReflect.serialize(val); + } + if (val !== undefined) { + unwrapped[name] = val; + } + }, this); + return unwrapped; + }, + reflectUnwrap: function (unwrapped) { + this.forEach(function (value, key) { + if (value !== undefined) { + unwrapped[key] = canReflect.unwrap(value); + } + }); + return unwrapped; + }, + log: function (key) { + var instance = this; + var quoteString = function quoteString(x) { + return typeof x === 'string' ? JSON.stringify(x) : x; + }; + var meta = ensureMeta(instance); + var allowed = meta.allowedLogKeysSet || new Set(); + meta.allowedLogKeysSet = allowed; + if (key) { + allowed.add(key); + } + meta._log = function (event, data) { + var type = event.type; + if (type === 'can.onPatches' || key && !allowed.has(type) || type === 'can.keys' || key && !allowed.has(type)) { + return; + } + if (type === 'add' || type === 'remove') { + dev.log(canReflect.getName(instance), '\n how ', quoteString(type), '\n what ', quoteString(data[0]), '\n index ', quoteString(data[1])); + } else { + dev.log(canReflect.getName(instance), '\n key ', quoteString(type), '\n is ', quoteString(data[0]), '\n was ', quoteString(data[1])); + } + }; + }, + deleteKey: function (prop) { + var instanceDefines = this._instanceDefinitions; + if (instanceDefines && Object.prototype.hasOwnProperty.call(instanceDefines, prop) && !Object.isSealed(this)) { + delete instanceDefines[prop]; + queues.batch.start(); + this.dispatch({ + type: 'can.keys', + target: this + }); + var oldValue = this._data[prop]; + if (oldValue !== undefined) { + delete this._data[prop]; + this.dispatch({ + type: prop, + target: this, + patches: [{ + type: 'delete', + key: prop + }] + }, [ + undefined, + oldValue + ]); + } + queues.batch.stop(); + } else { + this.set(prop, undefined); + } + return this; + } + }; + module.exports = defineHelpers; +}); +/*can-define@2.7.1#map/map*/ +define('can-define@2.7.1#map/map', [ + 'require', + 'exports', + 'module', + 'can-construct', + 'can-define', + '../define-helpers/define-helpers', + 'can-observation-recorder', + 'can-namespace', + 'can-log', + 'can-log/dev/dev', + 'can-reflect', + 'can-symbol', + 'can-queues', + 'can-event-queue/type/type' +], function (require, exports, module) { + 'use strict'; + var Construct = require('can-construct'); + var define = require('can-define'); + var defineHelpers = require('../define-helpers/define-helpers'); + var ObservationRecorder = require('can-observation-recorder'); + var ns = require('can-namespace'); + var canLog = require('can-log'); + var canLogDev = require('can-log/dev/dev'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var queues = require('can-queues'); + var addTypeEvents = require('can-event-queue/type/type'); + var keysForDefinition = function (definitions) { + var keys = []; + for (var prop in definitions) { + var definition = definitions[prop]; + if (typeof definition !== 'object' || ('serialize' in definition ? !!definition.serialize : !definition.get)) { + keys.push(prop); + } + } + return keys; + }; + function assign(source) { + queues.batch.start(); + canReflect.assignMap(this, source || {}); + queues.batch.stop(); + } + function update(source) { + queues.batch.start(); + canReflect.updateMap(this, source || {}); + queues.batch.stop(); + } + function assignDeep(source) { + queues.batch.start(); + canReflect.assignDeepMap(this, source || {}); + queues.batch.stop(); + } + function updateDeep(source) { + queues.batch.start(); + canReflect.updateDeepMap(this, source || {}); + queues.batch.stop(); + } + function setKeyValue(key, value) { + var defined = defineHelpers.defineExpando(this, key, value); + if (!defined) { + this[key] = value; + } + } + function getKeyValue(key) { + var value = this[key]; + if (value !== undefined || key in this || Object.isSealed(this)) { + return value; + } else { + ObservationRecorder.add(this, key); + return this[key]; + } + } + var getSchemaSymbol = canSymbol.for('can.getSchema'); + function getSchema() { + var def = this.prototype._define; + var definitions = def ? def.definitions : {}; + var schema = { + type: 'map', + identity: [], + keys: {} + }; + return define.updateSchemaKeys(schema, definitions); + } + var sealedSetup = function (props) { + define.setup.call(this, props || {}, this.constructor.seal); + }; + var DefineMap = Construct.extend('DefineMap', { + setup: function (base) { + var key, prototype = this.prototype; + if (DefineMap) { + var result = define(prototype, prototype, base.prototype._define); + define.makeDefineInstanceKey(this, result); + addTypeEvents(this); + for (key in DefineMap.prototype) { + define.defineConfigurableAndNotEnumerable(prototype, key, prototype[key]); + } + if (prototype.setup === DefineMap.prototype.setup) { + define.defineConfigurableAndNotEnumerable(prototype, 'setup', sealedSetup); + } + var _computedGetter = Object.getOwnPropertyDescriptor(prototype, '_computed').get; + Object.defineProperty(prototype, '_computed', { + configurable: true, + enumerable: false, + get: function () { + if (this === prototype) { + return; + } + return _computedGetter.call(this, arguments); + } + }); + } else { + for (key in prototype) { + define.defineConfigurableAndNotEnumerable(prototype, key, prototype[key]); + } + } + define.defineConfigurableAndNotEnumerable(prototype, 'constructor', this); + this[getSchemaSymbol] = getSchema; + } + }, { + setup: function (props, sealed) { + if (!this._define) { + Object.defineProperty(this, '_define', { + enumerable: false, + value: { definitions: {} } + }); + Object.defineProperty(this, '_data', { + enumerable: false, + value: {} + }); + } + define.setup.call(this, props || {}, sealed === true); + }, + get: function (prop) { + if (prop) { + return getKeyValue.call(this, prop); + } else { + return canReflect.unwrap(this, Map); + } + }, + set: function (prop, value) { + if (typeof prop === 'object') { + if (value === true) { + updateDeep.call(this, prop); + } else { + assignDeep.call(this, prop); + } + } else { + setKeyValue.call(this, prop, value); + } + return this; + }, + assignDeep: function (prop) { + assignDeep.call(this, prop); + return this; + }, + updateDeep: function (prop) { + updateDeep.call(this, prop); + return this; + }, + assign: function (prop) { + assign.call(this, prop); + return this; + }, + update: function (prop) { + update.call(this, prop); + return this; + }, + serialize: function () { + return canReflect.serialize(this, Map); + }, + deleteKey: defineHelpers.deleteKey, + forEach: function () { + var forEach = function (list, cb, thisarg) { + return canReflect.eachKey(list, cb, thisarg); + }, noObserve = ObservationRecorder.ignore(forEach); + return function (cb, thisarg, observe) { + return observe === false ? noObserve(this, cb, thisarg) : forEach(this, cb, thisarg); + }; + }(), + '*': { type: define.types.observable } + }); + var defineMapProto = { + 'can.isMapLike': true, + 'can.isListLike': false, + 'can.isValueLike': false, + 'can.getKeyValue': getKeyValue, + 'can.setKeyValue': setKeyValue, + 'can.deleteKeyValue': defineHelpers.deleteKey, + 'can.getOwnKeys': function () { + var keys = canReflect.getOwnEnumerableKeys(this); + if (this._computed) { + var computedKeys = canReflect.getOwnKeys(this._computed); + var key; + for (var i = 0; i < computedKeys.length; i++) { + key = computedKeys[i]; + if (keys.indexOf(key) < 0) { + keys.push(key); + } + } + } + return keys; + }, + 'can.getOwnEnumerableKeys': function () { + ObservationRecorder.add(this, 'can.keys'); + ObservationRecorder.add(Object.getPrototypeOf(this), 'can.keys'); + return keysForDefinition(this._define.definitions).concat(keysForDefinition(this._instanceDefinitions)); + }, + 'can.hasOwnKey': function (key) { + return Object.hasOwnProperty.call(this._define.definitions, key); + }, + 'can.hasKey': function (key) { + return !!this._define.definitions[key]; + }, + 'can.assignDeep': assignDeep, + 'can.updateDeep': updateDeep, + 'can.unwrap': defineHelpers.reflectUnwrap, + 'can.serialize': defineHelpers.reflectSerialize, + 'can.keyHasDependencies': function (key) { + return !!(this._computed && this._computed[key] && this._computed[key].compute); + }, + 'can.getKeyDependencies': function (key) { + var ret; + if (this._computed && this._computed[key] && this._computed[key].compute) { + ret = {}; + ret.valueDependencies = new Set(); + ret.valueDependencies.add(this._computed[key].compute); + } + return ret; + } + }; + canReflect.assignSymbols(DefineMap.prototype, defineMapProto); + canReflect.setKeyValue(DefineMap.prototype, canSymbol.iterator, function () { + return new define.Iterator(this); + }); + for (var prop in define.eventsProto) { + DefineMap[prop] = define.eventsProto[prop]; + Object.defineProperty(DefineMap.prototype, prop, { + enumerable: false, + value: define.eventsProto[prop], + writable: true + }); + } + var eventsProtoSymbols = 'getOwnPropertySymbols' in Object ? Object.getOwnPropertySymbols(define.eventsProto) : [ + canSymbol.for('can.onKeyValue'), + canSymbol.for('can.offKeyValue') + ]; + eventsProtoSymbols.forEach(function (sym) { + Object.defineProperty(DefineMap.prototype, sym, { + configurable: true, + enumerable: false, + value: define.eventsProto[sym], + writable: true + }); + }); + define.DefineMap = DefineMap; + Object.defineProperty(DefineMap.prototype, 'toObject', { + enumerable: false, + writable: true, + value: function () { + canLog.warn('Use DefineMap::get instead of DefineMap::toObject'); + return this.get(); + } + }); + module.exports = ns.DefineMap = DefineMap; +}); +/*can-define@2.7.1#list/list*/ +define('can-define@2.7.1#list/list', [ + 'require', + 'exports', + 'module', + 'can-construct', + 'can-define', + 'can-queues', + 'can-event-queue/type/type', + 'can-observation-recorder', + 'can-log', + 'can-log/dev/dev', + '../define-helpers/define-helpers', + 'can-assign', + 'can-diff/list/list', + 'can-namespace', + 'can-reflect', + 'can-symbol', + 'can-single-reference' +], function (require, exports, module) { + 'use strict'; + var Construct = require('can-construct'); + var define = require('can-define'); + var make = define.make; + var queues = require('can-queues'); + var addTypeEvents = require('can-event-queue/type/type'); + var ObservationRecorder = require('can-observation-recorder'); + var canLog = require('can-log'); + var canLogDev = require('can-log/dev/dev'); + var defineHelpers = require('../define-helpers/define-helpers'); + var assign = require('can-assign'); + var diff = require('can-diff/list/list'); + var ns = require('can-namespace'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var singleReference = require('can-single-reference'); + var splice = [].splice; + var runningNative = false; + var identity = function (x) { + return x; + }; + var localOnPatchesSymbol = 'can.patches'; + var makeFilterCallback = function (props) { + return function (item) { + for (var prop in props) { + if (item[prop] !== props[prop]) { + return false; + } + } + return true; + }; + }; + var onKeyValue = define.eventsProto[canSymbol.for('can.onKeyValue')]; + var offKeyValue = define.eventsProto[canSymbol.for('can.offKeyValue')]; + var getSchemaSymbol = canSymbol.for('can.getSchema'); + function getSchema() { + var definitions = this.prototype._define.definitions; + var schema = { + type: 'list', + keys: {} + }; + schema = define.updateSchemaKeys(schema, definitions); + if (schema.keys['#']) { + schema.values = definitions['#'].Type; + delete schema.keys['#']; + } + return schema; + } + var DefineList = Construct.extend('DefineList', { + setup: function (base) { + if (DefineList) { + addTypeEvents(this); + var prototype = this.prototype; + var result = define(prototype, prototype, base.prototype._define); + define.makeDefineInstanceKey(this, result); + var itemsDefinition = result.definitions['#'] || result.defaultDefinition; + if (itemsDefinition) { + if (itemsDefinition.Type) { + this.prototype.__type = make.set.Type('*', itemsDefinition.Type, identity); + } else if (itemsDefinition.type) { + this.prototype.__type = make.set.type('*', itemsDefinition.type, identity); + } + } + this[getSchemaSymbol] = getSchema; + } + } + }, { + setup: function (items) { + if (!this._define) { + Object.defineProperty(this, '_define', { + enumerable: false, + value: { + definitions: { + length: { type: 'number' }, + _length: { type: 'number' } + } + } + }); + Object.defineProperty(this, '_data', { + enumerable: false, + value: {} + }); + } + define.setup.call(this, {}, false); + Object.defineProperty(this, '_length', { + enumerable: false, + configurable: true, + writable: true, + value: 0 + }); + if (items) { + this.splice.apply(this, [ + 0, + 0 + ].concat(canReflect.toArray(items))); + } + }, + __type: define.types.observable, + _triggerChange: function (attr, how, newVal, oldVal) { + var index = +attr; + if (!isNaN(index)) { + var itemsDefinition = this._define.definitions['#']; + var patches, dispatched; + if (how === 'add') { + if (itemsDefinition && typeof itemsDefinition.added === 'function') { + ObservationRecorder.ignore(itemsDefinition.added).call(this, newVal, index); + } + patches = [{ + type: 'splice', + insert: newVal, + index: index, + deleteCount: 0 + }]; + dispatched = { + type: how, + patches: patches + }; + this.dispatch(dispatched, [ + newVal, + index + ]); + } else if (how === 'remove') { + if (itemsDefinition && typeof itemsDefinition.removed === 'function') { + ObservationRecorder.ignore(itemsDefinition.removed).call(this, oldVal, index); + } + patches = [{ + type: 'splice', + index: index, + deleteCount: oldVal.length + }]; + dispatched = { + type: how, + patches: patches + }; + this.dispatch(dispatched, [ + oldVal, + index + ]); + } else { + this.dispatch(how, [ + newVal, + index + ]); + } + } else { + this.dispatch({ + type: '' + attr, + target: this + }, [ + newVal, + oldVal + ]); + } + }, + get: function (index) { + if (arguments.length) { + if (isNaN(index)) { + ObservationRecorder.add(this, index); + } else { + ObservationRecorder.add(this, 'length'); + } + return this[index]; + } else { + return canReflect.unwrap(this, Map); + } + }, + set: function (prop, value) { + if (typeof prop !== 'object') { + prop = isNaN(+prop) || prop % 1 ? prop : +prop; + if (typeof prop === 'number') { + if (typeof prop === 'number' && prop > this._length - 1) { + var newArr = new Array(prop + 1 - this._length); + newArr[newArr.length - 1] = value; + this.push.apply(this, newArr); + return newArr; + } + this.splice(prop, 1, value); + } else { + var defined = defineHelpers.defineExpando(this, prop, value); + if (!defined) { + this[prop] = value; + } + } + } else { + if (canReflect.isListLike(prop)) { + if (value) { + this.replace(prop); + } else { + canReflect.assignList(this, prop); + } + } else { + canReflect.assignMap(this, prop); + } + } + return this; + }, + assign: function (prop) { + if (canReflect.isListLike(prop)) { + canReflect.assignList(this, prop); + } else { + canReflect.assignMap(this, prop); + } + return this; + }, + update: function (prop) { + if (canReflect.isListLike(prop)) { + canReflect.updateList(this, prop); + } else { + canReflect.updateMap(this, prop); + } + return this; + }, + assignDeep: function (prop) { + if (canReflect.isListLike(prop)) { + canReflect.assignDeepList(this, prop); + } else { + canReflect.assignDeepMap(this, prop); + } + return this; + }, + updateDeep: function (prop) { + if (canReflect.isListLike(prop)) { + canReflect.updateDeepList(this, prop); + } else { + canReflect.updateDeepMap(this, prop); + } + return this; + }, + _items: function () { + var arr = []; + this._each(function (item) { + arr.push(item); + }); + return arr; + }, + _each: function (callback) { + for (var i = 0, len = this._length; i < len; i++) { + callback(this[i], i); + } + }, + splice: function (index, howMany) { + var args = canReflect.toArray(arguments), added = [], i, len, listIndex, allSame = args.length > 2, oldLength = this._length; + index = index || 0; + for (i = 0, len = args.length - 2; i < len; i++) { + listIndex = i + 2; + args[listIndex] = this.__type(args[listIndex], listIndex); + added.push(args[listIndex]); + if (this[i + index] !== args[listIndex]) { + allSame = false; + } + } + if (allSame && this._length <= added.length) { + return added; + } + if (howMany === undefined) { + howMany = args[1] = this._length - index; + } + runningNative = true; + var removed = splice.apply(this, args); + runningNative = false; + queues.batch.start(); + if (howMany > 0) { + this._triggerChange('' + index, 'remove', undefined, removed); + } + if (args.length > 2) { + this._triggerChange('' + index, 'add', added, removed); + } + this.dispatch('length', [ + this._length, + oldLength + ]); + queues.batch.stop(); + return removed; + }, + serialize: function () { + return canReflect.serialize(this, Map); + } + }); + for (var prop in define.eventsProto) { + Object.defineProperty(DefineList.prototype, prop, { + enumerable: false, + value: define.eventsProto[prop], + writable: true + }); + } + var eventsProtoSymbols = 'getOwnPropertySymbols' in Object ? Object.getOwnPropertySymbols(define.eventsProto) : [ + canSymbol.for('can.onKeyValue'), + canSymbol.for('can.offKeyValue') + ]; + eventsProtoSymbols.forEach(function (sym) { + Object.defineProperty(DefineList.prototype, sym, { + configurable: true, + enumerable: false, + value: define.eventsProto[sym], + writable: true + }); + }); + var getArgs = function (args) { + return args[0] && Array.isArray(args[0]) ? args[0] : canReflect.toArray(args); + }; + canReflect.eachKey({ + push: 'length', + unshift: 0 + }, function (where, name) { + var orig = [][name]; + DefineList.prototype[name] = function () { + var args = [], len = where ? this._length : 0, i = arguments.length, res, val; + while (i--) { + val = arguments[i]; + args[i] = this.__type(val, i); + } + runningNative = true; + res = orig.apply(this, args); + runningNative = false; + if (!this.comparator || args.length) { + queues.batch.start(); + this._triggerChange('' + len, 'add', args, undefined); + this.dispatch('length', [ + this._length, + len + ]); + queues.batch.stop(); + } + return res; + }; + }); + canReflect.eachKey({ + pop: 'length', + shift: 0 + }, function (where, name) { + var orig = [][name]; + DefineList.prototype[name] = function () { + if (!this._length) { + return undefined; + } + var args = getArgs(arguments), len = where && this._length ? this._length - 1 : 0, oldLength = this._length ? this._length : 0, res; + runningNative = true; + res = orig.apply(this, args); + runningNative = false; + queues.batch.start(); + this._triggerChange('' + len, 'remove', undefined, [res]); + this.dispatch('length', [ + this._length, + oldLength + ]); + queues.batch.stop(); + return res; + }; + }); + canReflect.eachKey({ + 'map': 3, + 'filter': 3, + 'reduce': 4, + 'reduceRight': 4, + 'every': 3, + 'some': 3 + }, function a(fnLength, fnName) { + DefineList.prototype[fnName] = function () { + var self = this; + var args = [].slice.call(arguments, 0); + var callback = args[0]; + var thisArg = args[fnLength - 1] || self; + if (typeof callback === 'object') { + callback = makeFilterCallback(callback); + } + args[0] = function () { + var cbArgs = [].slice.call(arguments, 0); + cbArgs[fnLength - 3] = self.get(cbArgs[fnLength - 2]); + return callback.apply(thisArg, cbArgs); + }; + var ret = Array.prototype[fnName].apply(this, args); + if (fnName === 'map') { + return new DefineList(ret); + } else if (fnName === 'filter') { + return new self.constructor(ret); + } else { + return ret; + } + }; + }); + assign(DefineList.prototype, { + indexOf: function (item, fromIndex) { + for (var i = fromIndex || 0, len = this.length; i < len; i++) { + if (this.get(i) === item) { + return i; + } + } + return -1; + }, + lastIndexOf: function (item, fromIndex) { + fromIndex = typeof fromIndex === 'undefined' ? this.length - 1 : fromIndex; + for (var i = fromIndex; i >= 0; i--) { + if (this.get(i) === item) { + return i; + } + } + return -1; + }, + join: function () { + ObservationRecorder.add(this, 'length'); + return [].join.apply(this, arguments); + }, + reverse: function () { + var list = [].reverse.call(this._items()); + return this.replace(list); + }, + slice: function () { + ObservationRecorder.add(this, 'length'); + var temp = Array.prototype.slice.apply(this, arguments); + return new this.constructor(temp); + }, + concat: function () { + var args = []; + canReflect.eachIndex(arguments, function (arg) { + if (canReflect.isListLike(arg)) { + var arr = Array.isArray(arg) ? arg : canReflect.toArray(arg); + arr.forEach(function (innerArg) { + args.push(this.__type(innerArg)); + }, this); + } else { + args.push(this.__type(arg)); + } + }, this); + return new this.constructor(Array.prototype.concat.apply(canReflect.toArray(this), args)); + }, + forEach: function (cb, thisarg) { + var item; + for (var i = 0, len = this.length; i < len; i++) { + item = this.get(i); + if (cb.call(thisarg || item, item, i, this) === false) { + break; + } + } + return this; + }, + replace: function (newList) { + var patches = diff(this, newList); + queues.batch.start(); + for (var i = 0, len = patches.length; i < len; i++) { + this.splice.apply(this, [ + patches[i].index, + patches[i].deleteCount + ].concat(patches[i].insert)); + } + queues.batch.stop(); + return this; + }, + sort: function (compareFunction) { + var sorting = Array.prototype.slice.call(this); + Array.prototype.sort.call(sorting, compareFunction); + this.splice.apply(this, [ + 0, + sorting.length + ].concat(sorting)); + return this; + } + }); + for (var prop in define.eventsProto) { + DefineList[prop] = define.eventsProto[prop]; + Object.defineProperty(DefineList.prototype, prop, { + enumerable: false, + value: define.eventsProto[prop], + writable: true + }); + } + Object.defineProperty(DefineList.prototype, 'length', { + get: function () { + if (!this.__inSetup) { + ObservationRecorder.add(this, 'length'); + } + return this._length; + }, + set: function (newVal) { + if (runningNative) { + this._length = newVal; + return; + } + if (newVal == null || isNaN(+newVal) || newVal === this._length) { + return; + } + if (newVal > this._length - 1) { + var newArr = new Array(newVal - this._length); + this.push.apply(this, newArr); + } else { + this.splice(newVal); + } + }, + enumerable: true + }); + DefineList.prototype.attr = function (prop, value) { + canLog.warn('DefineMap::attr shouldn\'t be called'); + if (arguments.length === 0) { + return this.get(); + } else if (prop && typeof prop === 'object') { + return this.set.apply(this, arguments); + } else if (arguments.length === 1) { + return this.get(prop); + } else { + return this.set(prop, value); + } + }; + DefineList.prototype.item = function (index, value) { + if (arguments.length === 1) { + return this.get(index); + } else { + return this.set(index, value); + } + }; + DefineList.prototype.items = function () { + canLog.warn('DefineList::get should should be used instead of DefineList::items'); + return this.get(); + }; + var defineListProto = { + 'can.isMoreListLikeThanMapLike': true, + 'can.isMapLike': true, + 'can.isListLike': true, + 'can.isValueLike': false, + 'can.getKeyValue': DefineList.prototype.get, + 'can.setKeyValue': DefineList.prototype.set, + 'can.onKeyValue': function (key, handler, queue) { + var translationHandler; + if (isNaN(key)) { + return onKeyValue.apply(this, arguments); + } else { + translationHandler = function () { + handler(this[key]); + }; + singleReference.set(handler, this, translationHandler, key); + return onKeyValue.call(this, 'length', translationHandler, queue); + } + }, + 'can.offKeyValue': function (key, handler, queue) { + var translationHandler; + if (isNaN(key)) { + return offKeyValue.apply(this, arguments); + } else { + translationHandler = singleReference.getAndDelete(handler, this, key); + return offKeyValue.call(this, 'length', translationHandler, queue); + } + }, + 'can.deleteKeyValue': function (prop) { + prop = isNaN(+prop) || prop % 1 ? prop : +prop; + if (typeof prop === 'number') { + this.splice(prop, 1); + } else if (prop === 'length' || prop === '_length') { + return; + } else { + this.set(prop, undefined); + } + return this; + }, + 'can.assignDeep': function (source) { + queues.batch.start(); + canReflect.assignList(this, source); + queues.batch.stop(); + }, + 'can.updateDeep': function (source) { + queues.batch.start(); + this.replace(source); + queues.batch.stop(); + }, + 'can.keyHasDependencies': function (key) { + return !!(this._computed && this._computed[key] && this._computed[key].compute); + }, + 'can.getKeyDependencies': function (key) { + var ret; + if (this._computed && this._computed[key] && this._computed[key].compute) { + ret = {}; + ret.valueDependencies = new Set(); + ret.valueDependencies.add(this._computed[key].compute); + } + return ret; + }, + 'can.splice': function (index, deleteCount, insert) { + this.splice.apply(this, [ + index, + deleteCount + ].concat(insert)); + }, + 'can.onPatches': function (handler, queue) { + this[canSymbol.for('can.onKeyValue')](localOnPatchesSymbol, handler, queue); + }, + 'can.offPatches': function (handler, queue) { + this[canSymbol.for('can.offKeyValue')](localOnPatchesSymbol, handler, queue); + } + }; + canReflect.assignSymbols(DefineList.prototype, defineListProto); + canReflect.setKeyValue(DefineList.prototype, canSymbol.iterator, function () { + var index = -1; + if (typeof this.length !== 'number') { + this.length = 0; + } + return { + next: function () { + index++; + return { + value: this[index], + done: index >= this.length + }; + }.bind(this) + }; + }); + define.DefineList = DefineList; + module.exports = ns.DefineList = DefineList; +}); +/*can-component@4.4.9#can-component*/ +define('can-component@4.4.9#can-component', [ + 'require', + 'exports', + 'module', + './control/control', + 'can-namespace', + 'can-bind', + 'can-construct', + 'can-stache', + 'can-stache-bindings', + 'can-view-scope', + 'can-view-callbacks', + 'can-view-nodelist', + 'can-reflect', + 'can-stache-key', + 'can-simple-observable/setter/setter', + 'can-simple-observable', + 'can-simple-map', + 'can-define/map/map', + 'can-log', + 'can-log/dev/dev', + 'can-assign', + 'can-observation-recorder', + 'can-view-model', + 'can-define/list/list', + 'can-dom-data-state', + 'can-child-nodes', + 'can-string', + 'can-dom-events', + 'can-dom-mutate', + 'can-dom-mutate/node', + 'can-symbol', + 'can-globals/document/document' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var ComponentControl = require('./control/control'); + var namespace = require('can-namespace'); + var Bind = require('can-bind'); + var Construct = require('can-construct'); + var stache = require('can-stache'); + var stacheBindings = require('can-stache-bindings'); + var Scope = require('can-view-scope'); + var viewCallbacks = require('can-view-callbacks'); + var nodeLists = require('can-view-nodelist'); + var canReflect = require('can-reflect'); + var observeReader = require('can-stache-key'); + var SettableObservable = require('can-simple-observable/setter/setter'); + var SimpleObservable = require('can-simple-observable'); + var SimpleMap = require('can-simple-map'); + var DefineMap = require('can-define/map/map'); + var canLog = require('can-log'); + var canDev = require('can-log/dev/dev'); + var assign = require('can-assign'); + var ObservationRecorder = require('can-observation-recorder'); + require('can-view-model'); + require('can-define/list/list'); + var domData = require('can-dom-data-state'); + var getChildNodes = require('can-child-nodes'); + var string = require('can-string'); + var domEvents = require('can-dom-events'); + var domMutate = require('can-dom-mutate'); + var domMutateNode = require('can-dom-mutate/node'); + var canSymbol = require('can-symbol'); + var DOCUMENT = require('can-globals/document/document'); + var createdByCanComponentSymbol = canSymbol('can.createdByCanComponent'); + var getValueSymbol = canSymbol.for('can.getValue'); + var setValueSymbol = canSymbol.for('can.setValue'); + var viewInsertSymbol = canSymbol.for('can.viewInsert'); + var viewModelSymbol = canSymbol.for('can.viewModel'); + stache.addBindings(stacheBindings); + function addContext(el, tagData, insertionElementTagData) { + var vm; + domData.set.call(el, 'preventDataBindings', true); + var teardown = stacheBindings.behaviors.viewModel(el, insertionElementTagData, function (initialData, hasDataBinding, bindingState) { + if (bindingState && bindingState.isSettingOnViewModel === true) { + return vm = new SimpleMap(initialData); + } else { + return vm = new SimpleObservable(initialData); + } + }, undefined, true); + if (!teardown) { + return tagData; + } else { + return assign(assign({}, tagData), { + teardown: teardown, + scope: tagData.scope.add(vm) + }); + } + } + function makeInsertionTagCallback(tagName, componentTagData, shadowTagData, leakScope, getPrimaryTemplate) { + var options = shadowTagData.options; + return function hookupFunction(el, insertionElementTagData) { + var template = getPrimaryTemplate(el) || insertionElementTagData.subtemplate, renderingLightContent = template !== insertionElementTagData.subtemplate; + if (template) { + delete options.tags[tagName]; + var tagData; + if (renderingLightContent) { + if (leakScope.toLightContent) { + tagData = addContext(el, { + scope: insertionElementTagData.scope.cloneFromRef(), + options: insertionElementTagData.options + }, insertionElementTagData); + } else { + tagData = addContext(el, componentTagData, insertionElementTagData); + } + } else { + tagData = addContext(el, insertionElementTagData, insertionElementTagData); + } + var nodeList = nodeLists.register([el], function () { + if (tagData.teardown) { + tagData.teardown(); + } + }, insertionElementTagData.parentNodeList || true, insertionElementTagData.directlyNested); + nodeList.expression = ''; + var frag = template(tagData.scope, tagData.options, nodeList); + var newNodes = canReflect.toArray(getChildNodes(frag)); + var oldNodes = nodeLists.update(nodeList, newNodes); + nodeLists.replace(oldNodes, frag); + options.tags[tagName] = hookupFunction; + } + }; + } + function getSetupFunctionForComponentVM(componentInitVM) { + return ObservationRecorder.ignore(function (el, makeViewModel, initialVMData) { + var onCompleteBindings = []; + var onTeardowns = []; + var viewModel; + canReflect.eachKey(componentInitVM, function (parent, propName) { + var canGetParentValue = parent != null && !!parent[getValueSymbol]; + var canSetParentValue = parent != null && !!parent[setValueSymbol]; + if (canGetParentValue === true || canSetParentValue) { + var keysToRead = observeReader.reads(propName); + var child = new SettableObservable(function () { + return observeReader.read(viewModel, keysToRead).value; + }, function (newValue) { + canReflect.setKeyValue(viewModel, propName, newValue); + }); + var canBinding = new Bind({ + child: child, + parent: parent, + queue: 'domUI' + }); + canBinding.startParent(); + if (canGetParentValue === true) { + initialVMData[propName] = canBinding.parentValue; + } + onCompleteBindings.push(canBinding.start.bind(canBinding)); + onTeardowns.push(canBinding.stop.bind(canBinding)); + } else { + initialVMData[propName] = parent; + } + }); + viewModel = makeViewModel(initialVMData); + for (var i = 0, len = onCompleteBindings.length; i < len; i++) { + onCompleteBindings[i](); + } + return function () { + onTeardowns.forEach(function (onTeardown) { + onTeardown(); + }); + }; + }); + } + var Component = Construct.extend({ + setup: function () { + Construct.setup.apply(this, arguments); + if (Component) { + var self = this; + if (this.prototype.events !== undefined && canReflect.size(this.prototype.events) !== 0) { + this.Control = ComponentControl.extend(this.prototype.events); + } + var protoViewModel = this.prototype.viewModel || this.prototype.scope; + if (protoViewModel && this.prototype.ViewModel) { + throw new Error('Cannot provide both a ViewModel and a viewModel property'); + } + var vmName = string.capitalize(string.camelize(this.prototype.tag)) + 'VM'; + if (this.prototype.ViewModel) { + if (typeof this.prototype.ViewModel === 'function') { + this.ViewModel = this.prototype.ViewModel; + } else { + this.ViewModel = DefineMap.extend(vmName, {}, this.prototype.ViewModel); + } + } else { + if (protoViewModel) { + if (typeof protoViewModel === 'function') { + if (canReflect.isObservableLike(protoViewModel.prototype) && canReflect.isMapLike(protoViewModel.prototype)) { + this.ViewModel = protoViewModel; + } else { + this.viewModelHandler = protoViewModel; + } + } else { + if (canReflect.isObservableLike(protoViewModel) && canReflect.isMapLike(protoViewModel)) { + this.viewModelInstance = protoViewModel; + } else { + canLog.warn('can-component: ' + this.prototype.tag + ' is extending the viewModel into a can-simple-map'); + this.ViewModel = SimpleMap.extend(vmName, {}, protoViewModel); + } + } + } else { + this.ViewModel = SimpleMap.extend(vmName, {}, {}); + } + } + if (this.prototype.template) { + this.renderer = this.prototype.template; + } + if (this.prototype.view) { + this.renderer = this.prototype.view; + } + if (typeof this.renderer === 'string') { + var viewName = string.capitalize(string.camelize(this.prototype.tag)) + 'View'; + this.renderer = stache(viewName, this.renderer); + } + viewCallbacks.tag(this.prototype.tag, function (el, tagData) { + if (el[createdByCanComponentSymbol] === undefined) { + new self(el, tagData); + } + }); + } + } + }, { + setup: function (el, componentTagData) { + this._initialArgs = [ + el, + componentTagData + ]; + var component = this; + var options = { + helpers: {}, + tags: {} + }; + if (componentTagData === undefined) { + if (el === undefined) { + componentTagData = {}; + } else { + componentTagData = el; + el = undefined; + } + } + if (el === undefined) { + el = DOCUMENT().createElement(this.tag); + el[createdByCanComponentSymbol] = true; + } + this.element = el; + var componentContent = componentTagData.content; + if (componentContent !== undefined) { + if (typeof componentContent === 'function') { + componentTagData.subtemplate = componentContent; + } else if (typeof componentContent === 'string') { + componentTagData.subtemplate = stache(componentContent); + } + } + var componentScope = componentTagData.scope; + if (componentScope !== undefined && componentScope instanceof Scope === false) { + componentTagData.scope = new Scope(componentScope); + } + var componentTemplates = componentTagData.templates; + if (componentTemplates !== undefined) { + canReflect.eachKey(componentTemplates, function (template, name) { + if (typeof template === 'string') { + var debugName = name + ' template'; + componentTemplates[name] = stache(debugName, template); + } + }); + } + var teardownFunctions = []; + var initialViewModelData = {}; + var callTeardownFunctions = function () { + for (var i = 0, len = teardownFunctions.length; i < len; i++) { + teardownFunctions[i](); + } + }; + var preventDataBindings = domData.get.call(el, 'preventDataBindings'); + var viewModel, frag; + var teardownBindings; + if (preventDataBindings) { + viewModel = el[viewModelSymbol]; + } else { + var setupFn; + if (componentTagData.setupBindings) { + setupFn = componentTagData.setupBindings; + } else if (componentTagData.viewModel) { + setupFn = getSetupFunctionForComponentVM(componentTagData.viewModel); + } else { + setupFn = function (el, callback, data) { + return stacheBindings.behaviors.viewModel(el, componentTagData, callback, data); + }; + } + teardownBindings = setupFn(el, function (initialViewModelData) { + var ViewModel = component.constructor.ViewModel, viewModelHandler = component.constructor.viewModelHandler, viewModelInstance = component.constructor.viewModelInstance; + if (viewModelHandler) { + var scopeResult = viewModelHandler.call(component, initialViewModelData, componentTagData.scope, el); + if (canReflect.isObservableLike(scopeResult) && canReflect.isMapLike(scopeResult)) { + viewModelInstance = scopeResult; + } else if (canReflect.isObservableLike(scopeResult.prototype) && canReflect.isMapLike(scopeResult.prototype)) { + ViewModel = scopeResult; + } else { + ViewModel = SimpleMap.extend(scopeResult); + } + } + if (ViewModel) { + viewModelInstance = new component.constructor.ViewModel(initialViewModelData); + } + viewModel = viewModelInstance; + return viewModelInstance; + }, initialViewModelData); + } + this.viewModel = viewModel; + el[viewModelSymbol] = viewModel; + el.viewModel = viewModel; + domData.set.call(el, 'preventDataBindings', true); + if (this.helpers !== undefined) { + canReflect.eachKey(this.helpers, function (val, prop) { + if (typeof val === 'function') { + options.helpers[prop] = val.bind(viewModel); + } + }); + } + if (this.constructor.Control) { + this._control = new this.constructor.Control(el, { + scope: this.viewModel, + viewModel: this.viewModel, + destroy: callTeardownFunctions + }); + } else { + var removalDisposal = domMutate.onNodeRemoval(el, function () { + var doc = el.ownerDocument; + var rootNode = doc.contains ? doc : doc.documentElement; + if (!rootNode || !rootNode.contains(el)) { + removalDisposal(); + callTeardownFunctions(); + } + }); + } + var leakScope = { + toLightContent: this.leakScope === true, + intoShadowContent: this.leakScope === true + }; + var hasShadowTemplate = !!this.constructor.renderer; + var betweenTagsRenderer; + var betweenTagsTagData; + if (hasShadowTemplate) { + var shadowTagData; + if (leakScope.intoShadowContent) { + shadowTagData = { + scope: componentTagData.scope.add(this.viewModel, { viewModel: true }), + options: options + }; + } else { + shadowTagData = { + scope: new Scope(this.viewModel, null, { viewModel: true }), + options: options + }; + } + options.tags['can-slot'] = makeInsertionTagCallback('can-slot', componentTagData, shadowTagData, leakScope, function (el) { + var templates = componentTagData.templates; + if (templates) { + return templates[el.getAttribute('name')]; + } + }); + options.tags.content = makeInsertionTagCallback('content', componentTagData, shadowTagData, leakScope, function () { + return componentTagData.subtemplate; + }); + betweenTagsRenderer = this.constructor.renderer; + betweenTagsTagData = shadowTagData; + } else { + var lightTemplateTagData = { + scope: componentTagData.scope.add(this.viewModel, { viewModel: true }), + options: options + }; + betweenTagsTagData = lightTemplateTagData; + betweenTagsRenderer = componentTagData.subtemplate || el.ownerDocument.createDocumentFragment.bind(el.ownerDocument); + } + var disconnectedCallback, componentInPage; + var nodeList = nodeLists.register([], function () { + component._torndown = true; + domEvents.dispatch(el, 'beforeremove', false); + if (teardownBindings) { + teardownBindings(); + } + if (disconnectedCallback) { + disconnectedCallback(el); + } else if (typeof viewModel.stopListening === 'function') { + viewModel.stopListening(); + } + }, componentTagData.parentNodeList || true, false); + nodeList.expression = '<' + this.tag + '>'; + teardownFunctions.push(function () { + nodeLists.unregister(nodeList); + }); + this.nodeList = nodeList; + frag = betweenTagsRenderer(betweenTagsTagData.scope, betweenTagsTagData.options, nodeList); + domMutateNode.appendChild.call(el, frag); + nodeLists.update(nodeList, getChildNodes(el)); + if (viewModel && viewModel.connectedCallback) { + componentInPage = DOCUMENT().body.contains(el); + if (componentInPage) { + disconnectedCallback = viewModel.connectedCallback(el); + } else { + var insertionDisposal = domMutate.onNodeInsertion(el, function () { + insertionDisposal(); + disconnectedCallback = viewModel.connectedCallback(el); + }); + } + } + component._torndown = false; + } + }); + Component.prototype[viewInsertSymbol] = function (viewData) { + if (this._torndown) { + this.setup.apply(this, this._initialArgs); + } + viewData.nodeList.newDeepChildren.push(this.nodeList); + return this.element; + }; + module.exports = namespace.Component = Component; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-component@4.4.9#test/component-tag-test*/ +define('can-component@4.4.9#test/component-tag-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './helpers', + 'can-simple-map', + 'can-stache', + 'can-component' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var helpers = require('./helpers'); + var SimpleMap = require('can-simple-map'); + var stache = require('can-stache'); + var Component = require('can-component'); + helpers.makeTests('can-component tag', function () { + QUnit.test('hyphen-less tag names', function () { + Component.extend({ + tag: 'foobar', + view: stache('
    {{name}}
    '), + viewModel: function () { + return new SimpleMap({ name: 'Brian' }); + } + }); + var renderer = stache(''); + var frag = renderer(); + equal(frag.lastChild.firstChild.firstChild.nodeValue, 'Brian'); + }); + }); +}); +/*can-component@4.4.9#test/component-viewmodel-test*/ +define('can-component@4.4.9#test/component-viewmodel-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-dom-data-state', + './helpers', + 'can-simple-map', + 'can-stache', + 'can-component', + 'can-view-model', + 'can-define/map/map', + 'can-define/list/list', + 'can-view-scope', + 'can-simple-observable/setter/setter', + 'can-simple-observable', + 'can-reflect', + 'can-symbol', + 'can-dom-events', + 'can-dom-mutate/node', + 'can-construct', + 'can-view-callbacks' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var canData = require('can-dom-data-state'); + var helpers = require('./helpers'); + var SimpleMap = require('can-simple-map'); + var stache = require('can-stache'); + var Component = require('can-component'); + var canViewModel = require('can-view-model'); + var DefineMap = require('can-define/map/map'); + var DefineList = require('can-define/list/list'); + var Scope = require('can-view-scope'); + var SetterObservable = require('can-simple-observable/setter/setter'); + var SimpleObservable = require('can-simple-observable'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var domEvents = require('can-dom-events'); + var domMutateNode = require('can-dom-mutate/node'); + var Construct = require('can-construct'); + var tag = require('can-view-callbacks').tag; + var innerHTML = function (el) { + return el && el.innerHTML; + }; + helpers.makeTests('can-component viewModels', function () { + QUnit.test('a SimpleMap constructor as .ViewModel', function () { + var map = new SimpleMap({ name: 'Matthew' }); + Component.extend({ + tag: 'can-map-viewmodel', + view: stache('{{name}}'), + ViewModel: function () { + return map; + } + }); + var renderer = stache(''); + equal(renderer().firstChild.firstChild.nodeValue, 'Matthew'); + }); + QUnit.test('a SimpleMap as viewModel', function () { + var me = new SimpleMap({ name: 'Justin' }); + Component.extend({ + tag: 'my-viewmodel', + view: stache('{{name}}}'), + viewModel: me + }); + var renderer = stache(''); + equal(renderer().firstChild.firstChild.nodeValue, 'Justin'); + }); + QUnit.test('a SimpleMap constructor as viewModel', function () { + var MyMap = SimpleMap.extend({ + setup: function (props) { + props.name = 'Matthew'; + return SimpleMap.prototype.setup.apply(this, arguments); + } + }); + Component.extend({ + tag: 'can-map-viewmodel', + view: stache('{{name}}'), + viewModel: MyMap + }); + var renderer = stache(''); + equal(renderer().firstChild.firstChild.nodeValue, 'Matthew'); + }); + QUnit.test('an object is turned into a SimpleMap as viewModel', function () { + Component.extend({ + tag: 'can-map-viewmodel', + view: stache('{{name}}'), + viewModel: { name: 'Matthew' } + }); + var renderer = stache(''); + var fragOne = renderer(); + var vmOne = canViewModel(fragOne.firstChild); + var fragTwo = renderer(); + vmOne.set('name', 'Wilbur'); + equal(fragOne.firstChild.firstChild.nodeValue, 'Wilbur', 'The first map changed values'); + equal(fragTwo.firstChild.firstChild.nodeValue, 'Matthew', 'The second map did not change'); + }); + test('Providing viewModel and ViewModel throws', function () { + try { + Component.extend({ + tag: 'viewmodel-test', + view: stache('
    '), + viewModel: {}, + ViewModel: SimpleMap.extend({}) + }); + ok(false, 'Should have thrown because we provided both'); + } catch (er) { + ok(true, 'It threw because we provided both viewModel and ViewModel'); + } + }); + test('canViewModel utility', function () { + Component({ + tag: 'my-taggy-tag', + view: stache('

    hello

    '), + viewModel: function () { + return new SimpleMap({ foo: 'bar' }); + } + }); + var frag = stache('')(); + var el = frag.firstChild; + equal(canViewModel(el), el[canSymbol.for('can.viewModel')], 'one argument grabs the viewModel object'); + equal(canViewModel(el, 'foo'), 'bar', 'two arguments fetches a value'); + canViewModel(el, 'foo', 'baz'); + equal(canViewModel(el, 'foo'), 'baz', 'Three arguments sets the value'); + }); + test('setting passed variables - two way binding', function () { + Component.extend({ + tag: 'my-toggler', + view: stache('{{#if visible}}{{/if}}'), + leakScope: true, + ViewModel: DefineMap.extend({ + visible: { value: true }, + show: function () { + this.set('visible', true); + }, + hide: function () { + this.set('visible', false); + } + }) + }); + Component.extend({ + tag: 'my-app', + ViewModel: DefineMap.extend({ + visible: { value: true }, + show: function () { + this.set('visible', true); + } + }) + }); + var renderer = stache('' + '{{^visible}}{{/visible}}' + '' + 'content' + '' + '' + ''); + var frag = renderer({}); + var myApp = frag.firstChild, buttons = myApp.getElementsByTagName('button'); + equal(buttons.length, 1, 'there is one button'); + equal(innerHTML(buttons[0]), 'hide', 'the button\'s text is hide'); + domEvents.dispatch(buttons[0], 'click'); + buttons = myApp.getElementsByTagName('button'); + equal(buttons.length, 1, 'there is one button'); + equal(innerHTML(buttons[0]), 'show', 'the button\'s text is show'); + domEvents.dispatch(buttons[0], 'click'); + buttons = myApp.getElementsByTagName('button'); + equal(buttons.length, 1, 'there is one button'); + equal(innerHTML(buttons[0]), 'hide', 'the button\'s text is hide'); + }); + test('don\'t update computes unnecessarily', function () { + var sourceAge = new SimpleObservable(30), timesComputeIsCalled = 0; + var age = new SetterObservable(function () { + timesComputeIsCalled++; + if (timesComputeIsCalled === 1) { + ok(true, 'reading initial value to set as years'); + } else if (timesComputeIsCalled === 3) { + ok(true, 'called back another time after set to get the value'); + } else { + ok(false, '(getter) You\'ve called the callback ' + timesComputeIsCalled + ' times'); + } + return sourceAge.get(); + }, function (newVal) { + timesComputeIsCalled++; + if (timesComputeIsCalled === 2) { + ok(true, 'updating value to ' + newVal); + } else { + ok(false, '(setter) You\'ve called the callback ' + timesComputeIsCalled + ' times'); + } + sourceAge.set(newVal); + }); + Component.extend({ tag: 'age-er' }); + var renderer = stache(''); + renderer({ age: age }); + age.set(31); + }); + test('viewModel not rebound correctly (#550)', function () { + var nameChanges = 0; + Component.extend({ + tag: 'viewmodel-rebinder', + events: { + '{name}': function () { + nameChanges++; + } + } + }); + var renderer = stache(''); + var frag = renderer(); + var viewModel = canViewModel(frag.firstChild); + var n1 = new SimpleObservable(), n2 = new SimpleObservable(); + viewModel.set('name', n1); + n1.set('updated'); + viewModel.set('name', n2); + n2.set('updated'); + equal(nameChanges, 2); + }); + test('id and class should work now (#694)', function () { + Component.extend({ + tag: 'stay-classy', + ViewModel: SimpleMap.extend({ + setup: function (props) { + canReflect.assign(props, { + notid: 'foo', + notclass: 5, + notdataviewid: {} + }); + return SimpleMap.prototype.setup.apply(this, arguments); + } + }) + }); + var data = { + idData: 'id-success', + classData: 'class-success' + }; + var frag = stache('')(data); + var stayClassy = frag.firstChild; + domMutateNode.appendChild.call(this.fixture, frag); + var viewModel = canViewModel(stayClassy); + equal(viewModel.get('id'), 'id-success'); + equal(viewModel.get('class'), 'class-success'); + }); + test('Construct are passed normally', function () { + var Constructed = Construct.extend({ foo: 'bar' }, {}); + Component.extend({ + tag: 'con-struct', + view: stache('{{con.foo}}') + }); + var stached = stache(''); + var res = stached({ Constructed: Constructed }); + equal(innerHTML(res.firstChild), 'bar'); + }); + test('Component two way binding loop (#1579)', function () { + var changeCount = 0; + Component.extend({ + tag: 'product-swatch-color', + viewModel: { tag: 'product-swatch-color' } + }); + Component.extend({ + tag: 'product-swatch', + view: stache(''), + ViewModel: DefineMap.extend({ + variations: { + set: function (variations) { + if (changeCount > 500) { + return; + } + changeCount++; + return new DefineList(variations.get()); + } + } + }) + }); + var frag = stache('')(), productSwatch = frag.firstChild; + canViewModel(productSwatch).set('variations', new DefineList()); + ok(changeCount < 500, 'more than 500 events'); + }); + test('two-way binding syntax INTRODUCED in v2.3 ALLOWS a child property to initialize an undefined parent property', function () { + var renderer = stache(''); + Component.extend({ + tag: 'pa-rent', + view: stache('') + }); + Component.extend({ + tag: 'chi-ld', + ViewModel: { childProp: { value: 'bar' } } + }); + var frag = renderer({}); + var parentVM = canViewModel(frag.firstChild); + var childVM = canViewModel(frag.firstChild.firstChild); + equal(parentVM.get('parentProp'), 'bar', 'parentProp is bar'); + equal(childVM.get('childProp'), 'bar', 'childProp is bar'); + parentVM.set('parentProp', 'foo'); + equal(parentVM.get('parentProp'), 'foo', 'parentProp is foo'); + equal(childVM.get('childProp'), 'foo', 'childProp is foo'); + childVM.set('childProp', 'baz'); + equal(parentVM.get('parentProp'), 'baz', 'parentProp is baz'); + equal(childVM.get('childProp'), 'baz', 'childProp is baz'); + }); + test('conditional attributes (#2077)', function () { + Component.extend({ + tag: 'some-comp', + ViewModel: DefineMap.extend({ seal: false }, {}) + }); + var renderer = stache(''); + var map = new SimpleMap({ + preview: true, + nextPage: 2, + swapName: 'preview' + }); + var frag = renderer(map); + var vm = canViewModel(frag.firstChild); + var threads = [ + function () { + equal(vm.next, 2, 'has binding'); + equal(vm.swap, true, 'swap - has binding'); + map.attr('preview', false); + }, + function () { + equal(vm.swap, false, 'swap - updated binidng'); + map.attr('nextPage', 3); + equal(vm.next, 2, 'not updating after binding is torn down'); + map.attr('preview', true); + }, + function () { + equal(vm.next, 3, 're-initialized with binding'); + equal(vm.swap, true, 'swap - updated binidng'); + map.attr('swapName', 'nextPage'); + }, + function () { + equal(vm.swap, 3, 'swap - updated binding key'); + map.attr('nextPage', 4); + equal(vm.swap, 4, 'swap - updated binding'); + } + ]; + stop(); + var index = 0; + var next = function () { + if (index < threads.length) { + threads[index](); + index++; + setTimeout(next, 150); + } else { + start(); + } + }; + setTimeout(next, 100); + }); + QUnit.test('one-way - child to parent - parent that does not leak scope, but has no view', function () { + Component.extend({ + tag: 'outer-noleak', + ViewModel: DefineMap.extend('Outer', {}, { + name: { default: 'outer' }, + myChild: { default: null } + }), + leakScope: false + }); + Component.extend({ + tag: 'my-child', + ViewModel: DefineMap.extend('Inner', {}, { name: { default: 'inner' } }), + leakScope: false + }); + var renderer = stache(''); + var frag = renderer(); + var vm = canViewModel(frag.firstChild); + QUnit.equal(vm.myChild.name, 'inner', 'got instance'); + }); + QUnit.test('Can be called on an element using preventDataBindings (#183)', function () { + Component.extend({ + tag: 'prevent-data-bindings', + ViewModel: {}, + view: stache('{{value}}') + }); + var document = this.document; + var el = document.createElement('div'); + var callback = tag('prevent-data-bindings'); + var vm = new DefineMap({ value: 'it worked' }); + el[canSymbol.for('can.viewModel')] = vm; + canData.set.call(el, 'preventDataBindings', true); + callback(el, { scope: new Scope({ value: 'it did not work' }) }); + canData.set.call(el, 'preventDataBindings', false); + QUnit.equal(el.firstChild.nodeValue, 'it worked'); + }); + QUnit.test('viewModel available as viewModel property (#282)', function () { + Component.extend({ + tag: 'can-map-viewmodel', + view: stache('{{name}}'), + viewModel: { name: 'Matthew' } + }); + var renderer = stache(''); + var fragOne = renderer(); + var vmOne = fragOne.firstChild.viewModel; + var fragTwo = renderer(); + vmOne.set('name', 'Wilbur'); + equal(fragOne.firstChild.firstChild.nodeValue, 'Wilbur', 'The first map changed values'); + equal(fragTwo.firstChild.firstChild.nodeValue, 'Matthew', 'The second map did not change'); + }); + QUnit.test('connectedCallback without a disconnect calls stopListening', 1, function () { + QUnit.stop(); + var map = new SimpleMap(); + Component.extend({ + tag: 'connected-component-listen', + view: stache('rendered'), + ViewModel: { + connectedCallback: function (element) { + this.listenTo(map, 'foo', function () { + }); + } + } + }); + var template = stache(''); + var frag = template(); + var first = frag.firstChild; + domMutateNode.appendChild.call(this.fixture, frag); + helpers.afterMutation(function () { + domMutateNode.removeChild.call(first.parentNode, first); + helpers.afterMutation(function () { + QUnit.notOk(canReflect.isBound(map), 'stopListening no matter what on vm'); + QUnit.start(); + }); + }); + }); + }); +}); +/*can-observe@2.2.0#src/-symbols*/ +define('can-observe@2.2.0#src/-symbols', [ + 'require', + 'exports', + 'module', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var canSymbol = require('can-symbol'); + module.exports = { + metaSymbol: canSymbol.for('can.meta'), + patchesSymbol: 'can.patches', + keysSymbol: 'can.keys' + }; +}); +/*can-observe@2.2.0#src/-observable-store*/ +define('can-observe@2.2.0#src/-observable-store', function (require, exports, module) { + 'use strict'; + module.exports = { + proxiedObjects: new WeakMap(), + proxies: new WeakSet() + }; +}); +/*can-observe@2.2.0#src/-helpers*/ +define('can-observe@2.2.0#src/-helpers', [ + 'require', + 'exports', + 'module', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var canSymbol = require('can-symbol'); + var metaSymbol = canSymbol.for('can.meta'); + var classTest = /^\s*class\s+/; + var helpers = { + assignEverything: function (d, s) { + Object.getOwnPropertyNames(s).concat(Object.getOwnPropertySymbols(s)).forEach(function (key) { + Object.defineProperty(d, key, Object.getOwnPropertyDescriptor(s, key)); + }); + return d; + }, + isBuiltInButNotArrayOrPlainObject: function (obj) { + if (Array.isArray(obj)) { + return false; + } + if (typeof obj === 'function') { + var fnCode = obj.toString(); + if (fnCode.indexOf('[native code]') > 0) { + return true; + } else { + return false; + } + } else { + var toString = Object.prototype.toString.call(obj); + return toString !== '[object Object]' && toString.indexOf('[object ') !== -1; + } + }, + inheritsFromArray: function (obj) { + var cur = obj; + do { + if (Array.isArray(cur)) { + return true; + } + cur = Object.getPrototypeOf(cur); + } while (cur); + return false; + }, + isClass: function (obj) { + return typeof obj === 'function' && classTest.test(obj.toString()); + }, + supportsClass: function () { + try { + eval('"use strict"; class A{};'); + return true; + } catch (e) { + return false; + } + }(), + makeSimpleExtender: function (BaseType) { + return function extend(name, staticProps, prototypeProps) { + var Type = function () { + var source = this; + var instance = BaseType.apply(this, arguments); + if (source.init) { + instance[metaSymbol].preventSideEffects++; + source.init.apply(instance, arguments); + instance[metaSymbol].preventSideEffects--; + } + return instance; + }; + helpers.assignEverything(Type, BaseType); + helpers.assignEverything(Type, staticProps || {}); + Type.extend = helpers.makeSimpleExtender(Type); + Type.prototype = Object.create(BaseType.prototype); + helpers.assignEverything(Type.prototype, prototypeProps || {}); + Type.prototype.constructor = Type; + return Type; + }; + }, + assignNonEnumerable: function (obj, key, value) { + return Object.defineProperty(obj, key, { + enumerable: false, + writable: true, + configurable: true, + value: value + }); + } + }; + module.exports = helpers; +}); +/*can-observe@2.2.0#src/-computed-helpers*/ +define('can-observe@2.2.0#src/-computed-helpers', [ + 'require', + 'exports', + 'module', + 'can-observation', + 'can-observation-recorder', + 'can-event-queue/map/map', + 'can-reflect', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var Observation = require('can-observation'); + var ObservationRecorder = require('can-observation-recorder'); + var mapBindings = require('can-event-queue/map/map'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var canMeta = canSymbol.for('can.meta'); + var computedPropertyDefinitionSymbol = canSymbol.for('can.computedPropertyDefinitions'); + var onKeyValueSymbol = canSymbol.for('can.onKeyValue'); + var offKeyValueSymbol = canSymbol.for('can.offKeyValue'); + function ComputedObjectObservationData(instance, prop, observation) { + this.instance = instance; + this.prop = prop; + this.observation = observation; + this.forward = this.forward.bind(this); + } + ComputedObjectObservationData.prototype.bind = function () { + this.bindingCount++; + if (this.bindingCount === 1) { + this.observation.on(this.forward, 'notify'); + } + }; + ComputedObjectObservationData.prototype.unbind = function () { + this.bindingCount--; + if (this.bindingCount === 0) { + this.observation.off(this.forward, 'notify'); + } + }; + ComputedObjectObservationData.prototype.forward = function (newValue, oldValue) { + mapBindings.dispatch.call(this.instance, { + type: this.prop, + target: this.instance + }, [ + newValue, + oldValue + ]); + }; + ComputedObjectObservationData.prototype.bindingCount = 0; + function findComputed(instance, key) { + var meta = instance[canMeta]; + var target = meta.target; + var computedPropertyDefinitions = target[computedPropertyDefinitionSymbol]; + if (computedPropertyDefinitions === undefined) { + return; + } + var computedPropertyDefinition = computedPropertyDefinitions[key]; + if (computedPropertyDefinition === undefined) { + return; + } + if (meta.computedKeys[key] === undefined) { + meta.computedKeys[key] = new ComputedObjectObservationData(instance, key, computedPropertyDefinition(instance, key)); + } + return meta.computedKeys[key]; + } + var computedHelpers = module.exports = { + get: function (instance, key) { + var computedObj = findComputed(instance, key); + if (computedObj === undefined) { + return; + } + ObservationRecorder.add(instance, key.toString()); + if (computedObj.bindingCount === 0 && ObservationRecorder.isRecording()) { + Observation.temporarilyBind(computedObj.observation); + } + return { value: canReflect.getValue(computedObj.observation) }; + }, + set: function (instance, key, value) { + var computedObj = findComputed(instance, key); + if (computedObj === undefined) { + return false; + } + canReflect.setValue(computedObj.observation, value); + return true; + }, + bind: function (instance, key) { + var computedObj = findComputed(instance, key); + if (computedObj === undefined) { + return; + } + computedObj.bind(); + }, + unbind: function (instance, key) { + var computedObj = findComputed(instance, key); + if (computedObj === undefined) { + return; + } + computedObj.unbind(); + }, + addKeyDependencies: function (proxyKeys) { + var onKeyValue = proxyKeys[onKeyValueSymbol]; + var offKeyValue = proxyKeys[offKeyValueSymbol]; + canReflect.assignSymbols(proxyKeys, { + 'can.onKeyValue': function (key, handler, queue) { + computedHelpers.bind(this, key); + return onKeyValue.apply(this, arguments); + }, + 'can.offKeyValue': function (key, handler, queue) { + computedHelpers.unbind(this, key); + return offKeyValue.apply(this, arguments); + }, + 'can.getKeyDependencies': function (key) { + var computedObj = findComputed(this, key); + if (computedObj === undefined) { + return; + } + return { valueDependencies: new Set([computedObj.observation]) }; + } + }); + }, + addMethodsAndSymbols: function (Type) { + Type.prototype.addEventListener = function (key, handler, queue) { + computedHelpers.bind(this, key); + return mapBindings.addEventListener.call(this, key, handler, queue); + }; + Type.prototype.removeEventListener = function (key, handler, queue) { + computedHelpers.unbind(this, key); + return mapBindings.removeEventListener.call(this, key, handler, queue); + }; + }, + ensureDefinition: function (prototype) { + if (!prototype.hasOwnProperty(computedPropertyDefinitionSymbol)) { + var parent = prototype[computedPropertyDefinitionSymbol]; + var definitions = prototype[computedPropertyDefinitionSymbol] = Object.create(parent || null); + Object.getOwnPropertyNames(prototype).forEach(function (prop) { + if (prop === 'constructor') { + return; + } + var descriptor = Object.getOwnPropertyDescriptor(prototype, prop); + if (descriptor.get !== undefined) { + var getter = descriptor.get; + definitions[prop] = function (instance, property) { + return new Observation(getter, instance); + }; + } + }); + } + return prototype[computedPropertyDefinitionSymbol]; + } + }; +}); +/*can-observe@2.2.0#src/-make-object*/ +define('can-observe@2.2.0#src/-make-object', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-observation-recorder', + 'can-event-queue/map/map', + './-symbols', + './-observable-store', + './-helpers', + './-computed-helpers' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var ObservationRecorder = require('can-observation-recorder'); + var mapBindings = require('can-event-queue/map/map'); + var symbols = require('./-symbols'); + var observableStore = require('./-observable-store'); + var helpers = require('./-helpers'); + var computedHelpers = require('./-computed-helpers'); + var hasOwn = Object.prototype.hasOwnProperty; + var isSymbolLike = canReflect.isSymbolLike; + var proxyKeys = Object.create(null); + Object.getOwnPropertySymbols(mapBindings).forEach(function (symbol) { + helpers.assignNonEnumerable(proxyKeys, symbol, mapBindings[symbol]); + }); + computedHelpers.addKeyDependencies(proxyKeys); + var makeObject = { + observable: function (object, options) { + if (options.shouldRecordObservation === undefined) { + options.shouldRecordObservation = makeObject.shouldRecordObservationOnOwnAndMissingKeys; + } + var meta = { + target: object, + proxyKeys: options.proxyKeys !== undefined ? options.proxyKeys : Object.create(makeObject.proxyKeys()), + computedKeys: Object.create(null), + options: options, + preventSideEffects: 0 + }; + helpers.assignNonEnumerable(meta.proxyKeys, symbols.metaSymbol, meta); + var traps = { + get: makeObject.get.bind(meta), + set: makeObject.set.bind(meta), + ownKeys: makeObject.ownKeys.bind(meta), + deleteProperty: makeObject.deleteProperty.bind(meta), + getOwnPropertyDescriptor: makeObject.getOwnPropertyDescriptor.bind(meta), + meta: meta + }; + if (options.getPrototypeOf) { + traps.getPrototypeOf = options.getPrototypeOf; + } + meta.proxy = new Proxy(object, traps); + mapBindings.addHandlers(meta.proxy, meta); + return meta.proxy; + }, + proxyKeys: function () { + return proxyKeys; + }, + get: function (target, key, receiver) { + var proxyKey = this.proxyKeys[key]; + if (proxyKey !== undefined) { + return proxyKey; + } + if (isSymbolLike(key)) { + return target[key]; + } + var computedValue = computedHelpers.get(receiver, key); + if (computedValue !== undefined) { + return computedValue.value; + } + var keyInfo = makeObject.getKeyInfo(target, key, receiver, this); + var value = keyInfo.targetValue; + if (!keyInfo.valueIsInvariant) { + value = makeObject.getValueFromStore(key, value, this); + } + if (this.options.shouldRecordObservation(keyInfo, this)) { + ObservationRecorder.add(this.proxy, key.toString()); + } + if (keyInfo.parentObservableGetCalledOn) { + ObservationRecorder.add(keyInfo.parentObservableGetCalledOn, key.toString()); + } + return value; + }, + set: function (target, key, value, receiver) { + if (receiver !== this.proxy) { + return makeObject.setKey(receiver, key, value, this); + } + var computedValue = computedHelpers.set(receiver, key, value); + if (computedValue === true) { + return true; + } + value = makeObject.getValueToSet(key, value, this); + makeObject.setValueAndOnChange(key, value, this, function (key, value, meta, hadOwn, old) { + var dispatchArgs = { + type: key, + patches: [{ + key: key, + type: hadOwn ? 'set' : 'add', + value: value + }], + keyChanged: !hadOwn ? key : undefined + }; + mapBindings.dispatch.call(meta.proxy, dispatchArgs, [ + value, + old + ]); + }); + return true; + }, + deleteProperty: function (target, key) { + var old = this.target[key], deleteSuccessful = delete this.target[key]; + if (deleteSuccessful && this.preventSideEffects === 0 && old !== undefined) { + var dispatchArgs = { + type: key, + patches: [{ + key: key, + type: 'delete' + }], + keyChanged: key + }; + mapBindings.dispatch.call(this.proxy, dispatchArgs, [ + undefined, + old + ]); + } + return deleteSuccessful; + }, + ownKeys: function (target, key) { + ObservationRecorder.add(this.proxy, symbols.keysSymbol); + return Object.getOwnPropertyNames(this.target).concat(Object.getOwnPropertySymbols(this.target)).concat(Object.getOwnPropertySymbols(this.proxyKeys)); + }, + getOwnPropertyDescriptor: function (target, key) { + var desc = Object.getOwnPropertyDescriptor(target, key); + if (!desc && key in this.proxyKeys) { + return Object.getOwnPropertyDescriptor(this.proxyKeys, key); + } + return desc; + }, + getKeyInfo: function (target, key, receiver, meta) { + var descriptor = Object.getOwnPropertyDescriptor(target, key); + var propertyInfo = { + key: key, + descriptor: descriptor, + targetHasOwnKey: Boolean(descriptor), + getCalledOnParent: receiver !== meta.proxy, + protoHasKey: false, + valueIsInvariant: false, + targetValue: undefined, + isAccessor: false + }; + if (propertyInfo.getCalledOnParent === true) { + propertyInfo.parentObservableGetCalledOn = observableStore.proxiedObjects.get(receiver); + } + if (descriptor !== undefined) { + propertyInfo.valueIsInvariant = descriptor.writable === false; + if (descriptor.get !== undefined) { + propertyInfo.targetValue = descriptor.get.call(propertyInfo.parentObservableGetCalledOn || receiver); + propertyInfo.isAccessor = true; + } else { + propertyInfo.targetValue = descriptor.value; + } + } else { + propertyInfo.targetValue = meta.target[key]; + propertyInfo.protoHasKey = propertyInfo.targetValue !== undefined ? true : key in target; + } + return propertyInfo; + }, + shouldRecordObservationOnOwnAndMissingKeys: function (keyInfo, meta) { + return meta.preventSideEffects === 0 && !keyInfo.isAccessor && (keyInfo.targetHasOwnKey || !keyInfo.protoHasKey && !Object.isSealed(meta.target)); + }, + setKey: function (receiver, key, value) { + Object.defineProperty(receiver, key, { + value: value, + configurable: true, + enumerable: true, + writable: true + }); + return true; + }, + getValueToSet: function (key, value, meta) { + if (!canReflect.isSymbolLike(key) && meta.handlers.getNode([key])) { + return makeObject.getValueFromStore(key, value, meta); + } + return value; + }, + getValueFromStore: function (key, value, meta) { + if (!canReflect.isPrimitive(value) && !canReflect.isObservableLike(value) && !observableStore.proxies.has(value)) { + if (observableStore.proxiedObjects.has(value)) { + value = observableStore.proxiedObjects.get(value); + } else if (!helpers.isBuiltInButNotArrayOrPlainObject(value)) { + value = meta.options.observe(value); + } + } + return value; + }, + setValueAndOnChange: function (key, value, data, onChange) { + var old, change; + var hadOwn = hasOwn.call(data.target, key); + var descriptor = Object.getOwnPropertyDescriptor(data.target, key); + if (descriptor && descriptor.set) { + descriptor.set.call(data.proxy, value); + } else { + old = data.target[key]; + change = old !== value; + if (change) { + data.target[key] = value; + if (data.preventSideEffects === 0) { + onChange(key, value, data, hadOwn, old); + } + } + } + } + }; + module.exports = makeObject; +}); +/*can-observe@2.2.0#src/-make-array*/ +define('can-observe@2.2.0#src/-make-array', [ + 'require', + 'exports', + 'module', + 'can-observation-recorder', + 'can-event-queue/map/map', + 'can-reflect', + './-make-object', + './-symbols', + './-observable-store', + './-helpers', + './-computed-helpers' +], function (require, exports, module) { + 'use strict'; + var ObservationRecorder = require('can-observation-recorder'); + var mapBindings = require('can-event-queue/map/map'); + var canReflect = require('can-reflect'); + var makeObject = require('./-make-object'); + var symbols = require('./-symbols'); + var observableStore = require('./-observable-store'); + var helpers = require('./-helpers'); + var computedHelpers = require('./-computed-helpers'); + var isSymbolLike = canReflect.isSymbolLike; + var isInteger = Number.isInteger || function (value) { + return typeof value === 'number' && isFinite(value) && Math.floor(value) === value; + }; + function didLengthChangeCauseDeletions(key, value, old) { + return key === 'length' && value < old; + } + var mutateMethods = { + 'push': function (arr, args) { + return [{ + index: arr.length - args.length, + deleteCount: 0, + insert: args, + type: 'splice' + }]; + }, + 'pop': function (arr) { + return [{ + index: arr.length, + deleteCount: 1, + insert: [], + type: 'splice' + }]; + }, + 'shift': function () { + return [{ + index: 0, + deleteCount: 1, + insert: [], + type: 'splice' + }]; + }, + 'unshift': function (arr, args) { + return [{ + index: 0, + deleteCount: 0, + insert: args, + type: 'splice' + }]; + }, + 'splice': function (arr, args) { + return [{ + index: args[0], + deleteCount: args[1], + insert: args.slice(2), + type: 'splice' + }]; + }, + 'sort': function (arr) { + return [{ + index: 0, + deleteCount: arr.length, + insert: arr, + type: 'splice' + }]; + }, + 'reverse': function (arr, args, old) { + return [{ + index: 0, + deleteCount: arr.length, + insert: arr, + type: 'splice' + }]; + } + }; + canReflect.eachKey(mutateMethods, function (makePatches, prop) { + var protoFn = Array.prototype[prop]; + var mutateMethod = function () { + var meta = this[symbols.metaSymbol], makeSideEffects = meta.preventSideEffects === 0, oldLength = meta.target.length; + meta.preventSideEffects++; + var ret = protoFn.apply(meta.target, arguments); + var patches = makePatches(meta.target, Array.from(arguments), oldLength); + if (makeSideEffects === true) { + var dispatchArgs = { + type: 'length', + patches: patches + }; + mapBindings.dispatch.call(meta.proxy, dispatchArgs, [ + meta.target.length, + oldLength + ]); + } + meta.preventSideEffects--; + return ret; + }; + observableStore.proxiedObjects.set(protoFn, mutateMethod); + observableStore.proxies.add(mutateMethod); + }); + Object.getOwnPropertyNames(Array.prototype).forEach(function (prop) { + var protoFn = Array.prototype[prop]; + if (observableStore.proxiedObjects.has(protoFn)) { + return; + } + if (prop !== 'constructor' && typeof protoFn === 'function') { + var arrayMethod = function () { + ObservationRecorder.add(this, symbols.patchesSymbol); + var meta = this[symbols.metaSymbol]; + meta.preventSideEffects++; + var ret = protoFn.apply(this, arguments); + meta.preventSideEffects--; + return meta.options.observe(ret); + }; + observableStore.proxiedObjects.set(protoFn, arrayMethod); + observableStore.proxies.add(arrayMethod); + } + }); + var proxyKeys = helpers.assignEverything(Object.create(null), makeObject.proxyKeys()); + var makeArray = { + observable: function (array, options) { + if (options.shouldRecordObservation === undefined) { + options.shouldRecordObservation = makeObject.shouldRecordObservationOnOwnAndMissingKeys; + } + var meta = { + target: array, + proxyKeys: options.proxyKeys !== undefined ? options.proxyKeys : Object.create(makeArray.proxyKeys()), + computedKeys: Object.create(null), + options: options, + preventSideEffects: 0 + }; + meta.proxyKeys[symbols.metaSymbol] = meta; + meta.proxy = new Proxy(array, { + get: makeObject.get.bind(meta), + set: makeArray.set.bind(meta), + ownKeys: makeObject.ownKeys.bind(meta), + deleteProperty: makeObject.deleteProperty.bind(meta), + meta: meta + }); + mapBindings.addHandlers(meta.proxy, meta); + return meta.proxy; + }, + proxyKeys: function () { + return proxyKeys; + }, + set: function (target, key, value, receiver) { + if (receiver !== this.proxy) { + return makeObject.setKey(receiver, key, value, this); + } + var computedValue = computedHelpers.set(receiver, key, value); + if (computedValue === true) { + return true; + } + value = makeObject.getValueToSet(key, value, this); + var startingLength = target.length; + makeObject.setValueAndOnChange(key, value, this, function (key, value, meta, hadOwn, old) { + var patches = [{ + key: key, + type: hadOwn ? 'set' : 'add', + value: value + }]; + var numberKey = !isSymbolLike(key) && +key; + if (isInteger(numberKey)) { + if (!hadOwn && numberKey > startingLength) { + patches.push({ + index: startingLength, + deleteCount: 0, + insert: target.slice(startingLength), + type: 'splice' + }); + } else { + patches.push.apply(patches, mutateMethods.splice(target, [ + numberKey, + 1, + value + ])); + } + } + if (didLengthChangeCauseDeletions(key, value, old, meta)) { + patches.push({ + index: value, + deleteCount: old - value, + insert: [], + type: 'splice' + }); + } + var dispatchArgs = { + type: key, + patches: patches, + keyChanged: !hadOwn ? key : undefined + }; + mapBindings.dispatch.call(meta.proxy, dispatchArgs, [ + value, + old + ]); + }); + return true; + } + }; + module.exports = makeArray; +}); +/*can-observe@2.2.0#src/-make-observe*/ +define('can-observe@2.2.0#src/-make-observe', [ + 'require', + 'exports', + 'module', + 'can-reflect', + './-observable-store', + './-helpers' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var observables = require('./-observable-store'); + var helpers = require('./-helpers'); + var makeObserve = { + observe: function (value) { + if (canReflect.isPrimitive(value)) { + return value; + } + var observable = observables.proxiedObjects.get(value); + if (observable) { + return observable; + } + if (observables.proxies.has(value)) { + return value; + } + if (helpers.isBuiltInButNotArrayOrPlainObject(value)) { + return value; + } + if (typeof value === 'function') { + observable = makeObserve.function(value); + } else if (helpers.inheritsFromArray(value)) { + observable = makeObserve.array(value); + } else { + observable = makeObserve.object(value); + } + observables.proxiedObjects.set(value, observable); + observables.proxies.add(observable); + return observable; + }, + 'object': null, + 'array': null, + 'function': null + }; + module.exports = makeObserve; +}); +/*can-observe@2.2.0#src/-make-function*/ +define('can-observe@2.2.0#src/-make-function', [ + 'require', + 'exports', + 'module', + 'can-reflect', + './-make-object', + './-make-observe', + './-symbols', + './-observable-store', + 'can-event-queue/map/map', + 'can-event-queue/type/type', + './-helpers' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var makeObject = require('./-make-object'); + var makeObserve = require('./-make-observe'); + var symbols = require('./-symbols'); + var observableStore = require('./-observable-store'); + var mapBindings = require('can-event-queue/map/map'); + var typeBindings = require('can-event-queue/type/type'); + var helpers = require('./-helpers'); + var proxyKeys = helpers.assignEverything(Object.create(null), makeObject.proxyKeys()); + typeBindings(proxyKeys); + canReflect.assignSymbols(proxyKeys, { + 'can.defineInstanceKey': function (prop, value) { + this[symbols.metaSymbol].definitions[prop] = value; + } + }); + var makeFunction = { + observable: function (object, options) { + if (options.shouldRecordObservation === undefined) { + options.shouldRecordObservation = makeObject.shouldRecordObservationOnOwnAndMissingKeys; + } + var proxyKeys = Object.create(makeFunction.proxyKeys()); + var meta = { + target: object, + proxyKeys: proxyKeys, + computedKeys: Object.create(null), + options: options, + definitions: {}, + isClass: helpers.isClass(object), + preventSideEffects: 0 + }; + proxyKeys[symbols.metaSymbol] = meta; + meta.proxy = new Proxy(object, { + get: makeObject.get.bind(meta), + set: makeObject.set.bind(meta), + ownKeys: makeObject.ownKeys.bind(meta), + deleteProperty: makeObject.deleteProperty.bind(meta), + construct: makeFunction.construct.bind(meta), + apply: makeFunction.apply.bind(meta), + meta: meta + }); + mapBindings.addHandlers(meta.proxy, meta); + typeBindings.addHandlers(meta.proxy, meta); + observableStore.proxiedObjects.set(object, meta.proxy); + observableStore.proxies.add(meta.proxy); + if (meta.target.prototype && meta.target.prototype.constructor === meta.target) { + var newPrototype = makeObject.observable(meta.target.prototype, { + getPrototypeOf: function () { + return meta.target.prototype; + }, + observe: makeObserve.observe + }); + observableStore.proxiedObjects.set(meta.target.prototype, newPrototype); + observableStore.proxies.add(newPrototype); + var prototype = meta.proxy.prototype; + prototype.constructor = meta.proxy; + } + return meta.proxy; + }, + construct: function (target, argumentsList, newTarget) { + var instanceTarget, key; + if (this.isClass) { + instanceTarget = Reflect.construct(target, argumentsList, newTarget); + for (key in this.definitions) { + Object.defineProperty(instanceTarget, key, this.definitions[key]); + } + return this.options.observe(instanceTarget); + } else { + instanceTarget = Object.create(this.proxy.prototype); + for (key in this.definitions) { + Object.defineProperty(instanceTarget, key, this.definitions[key]); + } + var instance = this.options.observe(instanceTarget); + instance[symbols.metaSymbol].preventSideEffects++; + var res = target.apply(instance, argumentsList); + instance[symbols.metaSymbol].preventSideEffects--; + if (res) { + return res; + } else { + return instance; + } + } + }, + apply: function (target, thisArg, argumentsList) { + var ret = this.target.apply(thisArg, argumentsList); + return this.options.observe(ret); + }, + proxyKeys: function () { + return proxyKeys; + } + }; + module.exports = makeFunction; +}); +/*can-observe@2.2.0#src/-type-helpers*/ +define('can-observe@2.2.0#src/-type-helpers', [ + 'require', + 'exports', + 'module', + 'can-queues', + 'can-reflect', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var queues = require('can-queues'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var canMeta = canSymbol.for('can.meta'); + var typeDefinitionsSymbol = canSymbol.for('can.typeDefinitions'); + var helpers = module.exports = { + ensureDefinition: function (prototype) { + var typeDefs = prototype[typeDefinitionsSymbol]; + if (!typeDefs) { + var parent = prototype[typeDefinitionsSymbol]; + typeDefs = prototype[typeDefinitionsSymbol] = Object.create(parent || null); + } + return typeDefs; + }, + addMethodsAndSymbols: function (Type) { + canReflect.assignSymbols(Type, { + 'can.defineInstanceKey': function (prop, value) { + helpers.ensureDefinition(this.prototype)[prop] = value; + }, + 'can.dispatchInstanceBoundChange': function (obj, isBound) { + var meta = this[canMeta]; + if (meta) { + var lifecycleHandlers = meta.lifecycleHandlers; + if (lifecycleHandlers) { + queues.enqueueByQueue(lifecycleHandlers.getNode([]), this, [ + obj, + isBound + ]); + } + } + } + }); + }, + shouldRecordObservationOnAllKeysExceptFunctionsOnProto: function (keyInfo, meta) { + return meta.preventSideEffects === 0 && !keyInfo.isAccessor && (keyInfo.targetHasOwnKey || !keyInfo.protoHasKey && !Object.isSealed(meta.target) || keyInfo.protoHasKey && typeof targetValue !== 'function'); + } + }; +}); +/*can-observe@2.2.0#object/object*/ +define('can-observe@2.2.0#object/object', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-symbol', + '../src/-make-observe', + 'can-event-queue/map/map', + 'can-event-queue/type/type', + '../src/-helpers', + '../src/-make-object', + '../src/-observable-store', + '../src/-computed-helpers', + '../src/-type-helpers' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var makeObserve = require('../src/-make-observe'); + var eventMixin = require('can-event-queue/map/map'); + var typeEventMixin = require('can-event-queue/type/type'); + var helpers = require('../src/-helpers'); + var makeObject = require('../src/-make-object'); + var observableStore = require('../src/-observable-store'); + var definitionsSymbol = canSymbol.for('can.typeDefinitions'); + var computedHelpers = require('../src/-computed-helpers'); + var typeHelpers = require('../src/-type-helpers'); + var proxyKeys = helpers.assignEverything({}, makeObject.proxyKeys()); + computedHelpers.addKeyDependencies(proxyKeys); + var ObserveObject = function (props) { + var prototype = Object.getPrototypeOf(this); + computedHelpers.ensureDefinition(prototype); + typeHelpers.ensureDefinition(prototype); + var sourceInstance = this; + var definitions = prototype[definitionsSymbol] || {}; + for (var key in definitions) { + Object.defineProperty(sourceInstance, key, definitions[key]); + } + if (props !== undefined) { + canReflect.assign(sourceInstance, props); + } + var localProxyKeys = Object.create(proxyKeys); + localProxyKeys.constructor = this.constructor; + var observable = makeObject.observable(sourceInstance, { + observe: makeObserve.observe, + proxyKeys: localProxyKeys, + shouldRecordObservation: typeHelpers.shouldRecordObservationOnAllKeysExceptFunctionsOnProto + }); + observableStore.proxiedObjects.set(sourceInstance, observable); + observableStore.proxies.add(observable); + return observable; + }; + eventMixin(ObserveObject.prototype); + typeEventMixin(ObserveObject); + computedHelpers.addMethodsAndSymbols(ObserveObject); + typeHelpers.addMethodsAndSymbols(ObserveObject); + ObserveObject.extend = helpers.makeSimpleExtender(ObserveObject); + module.exports = ObserveObject; +}); +/*can-observe@2.2.0#array/array*/ +define('can-observe@2.2.0#array/array', [ + 'require', + 'exports', + 'module', + 'can-symbol', + '../src/-make-array', + '../src/-make-observe', + 'can-event-queue/map/map', + 'can-event-queue/type/type', + '../src/-helpers', + '../src/-observable-store', + '../src/-computed-helpers', + '../src/-type-helpers' +], function (require, exports, module) { + 'use strict'; + var canSymbol = require('can-symbol'); + var makeArray = require('../src/-make-array'); + var makeObserve = require('../src/-make-observe'); + var eventMixin = require('can-event-queue/map/map'); + var typeEventMixin = require('can-event-queue/type/type'); + var helpers = require('../src/-helpers'); + var observableStore = require('../src/-observable-store'); + var computedHelpers = require('../src/-computed-helpers'); + var typeHelpers = require('../src/-type-helpers'); + var definitionsSymbol = canSymbol.for('can.typeDefinitions'); + var proxyKeys = helpers.assignEverything({}, makeArray.proxyKeys()); + var ObserveArray; + if (false) { + } else { + var ObserveArray = function (items) { + var prototype = Object.getPrototypeOf(this); + computedHelpers.ensureDefinition(prototype); + typeHelpers.ensureDefinition(prototype); + var instance = this; + var definitions = prototype[definitionsSymbol] || {}; + for (var key in definitions) { + Object.defineProperty(instance, key, definitions[key]); + } + this.push.apply(this, items || []); + var localProxyKeys = Object.create(proxyKeys); + localProxyKeys.constructor = this.constructor; + var observable = makeArray.observable(instance, { + observe: makeObserve.observe, + proxyKeys: localProxyKeys, + shouldRecordObservation: typeHelpers.shouldRecordObservationOnAllKeysExceptFunctionsOnProto + }); + observableStore.proxiedObjects.set(instance, observable); + observableStore.proxies.add(observable); + return observable; + }; + ObserveArray.prototype = Object.create(Array.prototype); + } + eventMixin(ObserveArray.prototype); + typeEventMixin(ObserveArray); + computedHelpers.addMethodsAndSymbols(ObserveArray); + typeHelpers.addMethodsAndSymbols(ObserveArray); + ObserveArray.extend = helpers.makeSimpleExtender(ObserveArray); + module.exports = ObserveArray; +}); +/*can-observe@2.2.0#decorators/decorators*/ +define('can-observe@2.2.0#decorators/decorators', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-simple-observable/async/async', + 'can-simple-observable/resolver/resolver', + '../src/-computed-helpers' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var AsyncObservable = require('can-simple-observable/async/async'); + var ResolverObservable = require('can-simple-observable/resolver/resolver'); + var computedHelpers = require('../src/-computed-helpers'); + function defineProperty(prototype, prop, makeObservable) { + computedHelpers.ensureDefinition(prototype)[prop] = makeObservable; + } + function asyncBase(config) { + return function (target, key, descriptor) { + if (descriptor.get !== undefined) { + var getter = descriptor.get; + return defineProperty(target, key, function (instance, property) { + function fn(lastSet, resolve) { + if (!resolve) { + return config.default; + } + var promise = getter.call(this, true); + if (canReflect.isPromise(promise)) { + promise.then(resolve); + return config.default; + } + } + return new AsyncObservable(fn, instance, config.default); + }); + } + if (descriptor.value !== undefined) { + var method = descriptor.value; + return defineProperty(target, key, function (instance, property) { + return new AsyncObservable(function (lastSet, resolve) { + return method.call(this, resolve); + }, instance, config.default); + }); + } + }; + } + function resolverBase(config) { + return function (target, key, descriptor) { + if (descriptor.value !== undefined) { + var method = descriptor.value; + return defineProperty(target, key, function (instance, property) { + return new ResolverObservable(method, instance); + }); + } + }; + } + function optionalConfig(decorator) { + function wrapper(config) { + if (arguments.length === 3) { + return decorator({}).apply(null, arguments); + } + return decorator(config); + } + return wrapper; + } + module.exports = { + async: optionalConfig(asyncBase), + resolver: optionalConfig(resolverBase) + }; +}); +/*can-observe@2.2.0#can-observe*/ +define('can-observe@2.2.0#can-observe', [ + 'require', + 'exports', + 'module', + './src/-make-object', + './src/-make-array', + './src/-make-function', + './src/-make-observe', + './object/object', + './array/array', + './src/-computed-helpers', + './decorators/decorators' +], function (require, exports, module) { + 'use strict'; + var makeObject = require('./src/-make-object'); + var makeArray = require('./src/-make-array'); + var makeFunction = require('./src/-make-function'); + var makeObserve = require('./src/-make-observe'); + var ObserveObject = require('./object/object'); + var ObserveArray = require('./array/array'); + var computedHelpers = require('./src/-computed-helpers'); + var decorators = require('./decorators/decorators'); + makeObserve.object = function (object) { + return makeObject.observable(object, makeObserve); + }; + makeObserve.array = function (array) { + return makeArray.observable(array, makeObserve); + }; + makeObserve.function = function (array) { + return makeFunction.observable(array, makeObserve); + }; + makeObserve.observe.Object = ObserveObject; + makeObserve.observe.Array = ObserveArray; + module.exports = makeObserve.observe; + module.exports.defineProperty = function (prototype, prop, makeObservable) { + computedHelpers.ensureDefinition(prototype)[prop] = makeObservable; + }; + for (var key in decorators) { + module.exports[key] = decorators[key]; + } +}); +/*can-component@4.4.9#test/component-viewmodel-observe-test*/ +define('can-component@4.4.9#test/component-viewmodel-observe-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './helpers', + 'can-stache', + 'can-component', + 'can-dom-events', + 'can-dom-mutate/node', + 'can-observe' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var helpers = require('./helpers'); + var stache = require('can-stache'); + var Component = require('can-component'); + var domEvents = require('can-dom-events'); + var domMutateNode = require('can-dom-mutate/node'); + var observe = require('can-observe'); + var classSupport = function () { + try { + eval('"use strict"; class A{};'); + return true; + } catch (e) { + return false; + } + }(); + helpers.makeTests('can-component viewModels with observe', function () { + QUnit.test('Basic can-observe type', function () { + Component.extend({ + tag: 'observe-add', + view: stache('{{count}}'), + ViewModel: observe.Object.extend('ObserveAdd', {}, { + count: 0, + add: function () { + this.count++; + } + }) + }); + var frag = stache('')(); + var buttons = frag.firstChild.getElementsByTagName('button'); + var spans = frag.firstChild.getElementsByTagName('span'); + QUnit.equal(spans[0].innerHTML, '0', 'first value'); + domEvents.dispatch(buttons[0], 'click'); + QUnit.equal(spans[0].innerHTML, '1', 'second value'); + }); + if (classSupport) { + QUnit.test('ViewModel as observe(class)', function () { + class Add extends observe.Object { + constructor(props) { + super(props); + this.count = 0; + } + add() { + this.count++; + } + } + Component.extend({ + tag: 'observe-class-add', + view: stache('{{count}}'), + ViewModel: Add + }); + var frag = stache('')(); + var buttons = frag.firstChild.getElementsByTagName('button'); + var spans = frag.firstChild.getElementsByTagName('span'); + QUnit.equal(spans[0].innerHTML, '0', 'first value'); + domEvents.dispatch(buttons[0], 'click'); + QUnit.equal(spans[0].innerHTML, '1', 'second value'); + }); + QUnit.test('connectedCallback and disconnectedCallback', 3, function () { + QUnit.stop(); + Component.extend({ + tag: 'connected-component', + view: stache('rendered'), + ViewModel: class extends observe.Object { + connectedCallback(element) { + QUnit.equal(element.innerHTML, 'rendered', 'rendered view'); + QUnit.equal(element.nodeName, 'CONNECTED-COMPONENT', 'connectedCallback'); + return function () { + QUnit.equal(element.nodeName, 'CONNECTED-COMPONENT', 'disconnectedCallback'); + }; + } + } + }); + var template = stache(''); + var frag = template(); + var first = frag.firstChild; + domMutateNode.appendChild.call(this.fixture, frag); + helpers.afterMutation(function () { + domMutateNode.removeChild.call(first.parentNode, first); + helpers.afterMutation(function () { + QUnit.start(); + }); + }); + }); + } + }); +}); +/*can-dom-mutate@1.3.5#dom-events*/ +define('can-dom-mutate@1.3.5#dom-events', [ + 'require', + 'exports', + 'module', + 'can-dom-mutate', + 'can-namespace' +], function (require, exports, module) { + 'use strict'; + var domMutate = require('can-dom-mutate'); + var namespace = require('can-namespace'); + function makeMutationEvent(defaultEventType, subscription, bubbles) { + var elementSubscriptions = new Map(); + return { + _subscriptions: elementSubscriptions, + defaultEventType: defaultEventType, + addEventListener: function (target, eventType, handler) { + var dispatch = this.dispatch; + var data = elementSubscriptions.get(target); + if (!data) { + data = { + removeListener: null, + listeners: new Set() + }; + elementSubscriptions.set(target, data); + } + if (data.listeners.size === 0) { + data.removeListener = subscription(target, function (mutation) { + var eventData = { type: eventType }; + for (var key in mutation) { + eventData[key] = mutation[key]; + } + dispatch(target, eventData, bubbles !== false); + }); + } + data.listeners.add(handler); + target.addEventListener(eventType, handler); + }, + removeEventListener: function (target, eventType, handler) { + target.removeEventListener(eventType, handler); + var data = elementSubscriptions.get(target); + if (data) { + data.listeners['delete'](handler); + if (data.listeners.size === 0) { + data.removeListener(); + elementSubscriptions['delete'](target); + } + } + } + }; + } + module.exports = namespace.domMutateDomEvents = { + attributes: makeMutationEvent('attributes', domMutate.onNodeAttributeChange), + inserted: makeMutationEvent('inserted', domMutate.onNodeInsertion, false), + removed: makeMutationEvent('removed', domMutate.onNodeRemoval) + }; +}); +/*can-component@4.4.9#test/component-view-test*/ +define('can-component@4.4.9#test/component-view-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './helpers', + 'can-simple-map', + 'can-stache', + 'can-component', + 'can-dom-events', + 'can-dom-mutate/node', + 'can-dom-mutate/dom-events', + 'can-view-model', + 'can-define/map/map', + 'can-queues', + 'can-fragment', + 'can-view-callbacks', + 'can-view-scope' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var helpers = require('./helpers'); + var SimpleMap = require('can-simple-map'); + var stache = require('can-stache'); + var Component = require('can-component'); + var domEvents = require('can-dom-events'); + var domMutateNode = require('can-dom-mutate/node'); + var domMutateDomEvents = require('can-dom-mutate/dom-events'); + var insertedEvent = domMutateDomEvents.inserted; + var canViewModel = require('can-view-model'); + var DefineMap = require('can-define/map/map'); + var queues = require('can-queues'); + var getFragment = require('can-fragment'); + var viewCallbacks = require('can-view-callbacks'); + var Scope = require('can-view-scope'); + var innerHTML = function (el) { + return el && el.innerHTML; + }; + helpers.makeTests('can-component views', function (doc, runTestInOnlyDocument) { + QUnit.test('lexical scoping', function () { + Component.extend({ + tag: 'hello-world', + view: stache('{{greeting}} World{{exclamation}}'), + viewModel: function () { + return new SimpleMap({ greeting: 'Hello' }); + } + }); + var renderer = stache('{{greeting}}'); + var frag = renderer({ + greeting: 'World', + exclamation: '!' + }); + var hello = frag.firstChild; + equal(hello.innerHTML.trim(), 'Hello World'); + Component.extend({ + tag: 'hello-world-no-template', + leakScope: false, + viewModel: function () { + return new SimpleMap({ greeting: 'Hello' }); + } + }); + renderer = stache('{{greeting}}'); + frag = renderer({ + greeting: 'World', + exclamation: '!' + }); + hello = frag.firstChild; + equal(hello.innerHTML.trim(), 'Hello', 'If no view is provided to Component, treat bindings as dynamic.'); + }); + QUnit.test('dynamic scoping', function () { + Component.extend({ + tag: 'hello-world', + leakScope: true, + view: stache('{{greeting}} World{{../exclamation}}'), + viewModel: function () { + return new SimpleMap({ greeting: 'Hello' }); + } + }); + var renderer = stache('{{greeting}}'); + var frag = renderer({ + greeting: 'World', + exclamation: '!' + }); + var hello = frag.firstChild; + equal(hello.innerHTML.trim(), 'Hello Hello!'); + }); + QUnit.test('hello-world and whitespace around custom elements', function () { + Component.extend({ + tag: 'hello-world', + view: stache('{{#if visible}}{{message}}{{else}}Click me{{/if}}'), + viewModel: function () { + return new SimpleMap({ + visible: false, + message: 'Hello There!' + }); + }, + events: { + click: function () { + this.viewModel.attr('visible', true); + } + } + }); + var renderer = stache(' '); + var frag = renderer({}); + var helloWorld = frag.childNodes.item(1); + domEvents.dispatch(helloWorld, 'click'); + equal(helloWorld.innerHTML, 'Hello There!'); + }); + QUnit.test('self closing content tags', function () { + Component.extend({ + 'tag': 'my-greeting', + view: stache('

    '), + viewModel: function () { + return new SimpleMap({ title: 'Component' }); + } + }); + var renderer = stache('{{site}} - {{title}}'); + var frag = renderer({ site: 'CanJS' }); + equal(frag.firstChild.getElementsByTagName('span').length, 1, 'there is an h1'); + }); + QUnit.test('content extension stack overflow error', function () { + Component({ + tag: 'outer-tag', + view: stache('inner-tag CONTENT ') + }); + Component({ + tag: 'inner-tag', + view: stache('inner-tag TEMPLATE ') + }); + var renderer = stache('outer-tag CONTENT'); + var frag = renderer(); + equal(innerHTML(frag.firstChild.firstChild), 'inner-tag TEMPLATE inner-tag CONTENT outer-tag CONTENT'); + }); + QUnit.test('inserted event fires twice if component inside live binding block', function () { + var undo = domEvents.addEvent(insertedEvent); + var inited = 0, inserted = 0; + Component.extend({ + tag: 'child-tag', + ViewModel: DefineMap.extend({ + init: function () { + inited++; + } + }), + events: { + ' inserted': function () { + inserted++; + } + } + }); + Component.extend({ + tag: 'parent-tag', + view: stache('{{#shown}}{{/shown}}'), + viewModel: DefineMap.extend('ParentTag', {}, { shown: { default: false } }), + events: { + ' inserted': function () { + this.viewModel.shown = true; + } + } + }); + var frag = stache('')({}); + domMutateNode.appendChild.call(this.fixture, frag); + stop(); + var attempts = 0; + function checkCount() { + if (inserted >= 1 || attempts > 100) { + equal(inited, 1, 'inited'); + equal(inserted, 1, 'inserted'); + undo(); + start(); + } else { + attempts += 1; + setTimeout(checkCount, 30); + } + } + checkCount(); + }); + QUnit.test('Same component tag nested', function () { + Component({ + 'tag': 'my-tag', + view: stache('

    ') + }); + var renderer = stache('
    OutterInner
    '); + var renderer2 = stache('
    3210
    '); + var renderer3 = stache('
    FirstSecond
    '); + equal(renderer({}).firstChild.getElementsByTagName('p').length, 2, 'proper number of p tags'); + equal(renderer2({}).firstChild.getElementsByTagName('p').length, 4, 'proper number of p tags'); + equal(renderer3({}).firstChild.getElementsByTagName('p').length, 2, 'proper number of p tags'); + }); + QUnit.test('nested component within an #if is not live bound(#1025)', function () { + Component.extend({ + tag: 'parent-component', + view: stache('{{#if shown}}{{/if}}'), + viewModel: function () { + return new SimpleMap({ shown: false }); + } + }); + Component.extend({ + tag: 'child-component', + view: stache('Hello world.') + }); + var renderer = stache(''); + var frag = renderer({}); + equal(innerHTML(frag.firstChild), '', 'child component is not inserted'); + canViewModel(frag.firstChild).attr('shown', true); + equal(innerHTML(frag.firstChild.firstChild), 'Hello world.', 'child component is inserted'); + canViewModel(frag.firstChild).attr('shown', false); + equal(innerHTML(frag.firstChild), '', 'child component is removed'); + }); + QUnit.test('references scopes are available to bindings nested in components (#2029)', function () { + var renderer = stache('' + ''); + Component.extend({ tag: 'wrap-er' }); + Component.extend({ + tag: 'export-er', + events: { + 'init': function () { + var self = this.viewModel; + stop(); + setTimeout(function () { + self.set('value', 100); + var wrapper = frag.lastChild, simpleExample = wrapper.firstChild, textNode = simpleExample.firstChild; + equal(textNode.nodeValue, '100', 'updated value with reference'); + start(); + }, 100); + } + } + }); + Component.extend({ + tag: 'simple-example', + view: stache('{{key}}') + }); + var frag = renderer({}); + }); + test(' (#2151)', function () { + var mapInstance = new DefineMap({ + items: [ + { + id: 1, + context: 'Item 1', + render: false + }, + { + id: 2, + context: 'Item 2', + render: false + } + ] + }); + Component.extend({ + tag: 'list-items', + view: stache('
      ' + '{{#items}}' + '{{#if render}}' + '
    • ' + '{{/if}}' + '{{/items}}' + '
    '), + viewModel: mapInstance, + leakScope: true + }); + Component.extend({ + tag: 'list-item', + view: stache('{{item.context}}') + }); + var renderer = stache(''); + var frag = renderer(); + queues.batch.start(); + canViewModel(frag.firstChild).get('items').forEach(function (item, index) { + item.set('render', true); + }); + queues.batch.stop(); + var lis = frag.firstChild.getElementsByTagName('li'); + ok(innerHTML(lis[0]).indexOf('Item 1') >= 0, 'Item 1 written out'); + ok(innerHTML(lis[1]).indexOf('Item 2') >= 0, 'Item 2 written out'); + }); + QUnit.test('two-way - reference - with tag', function () { + Component.extend({ + tag: 'other-export', + viewModel: function () { + return new SimpleMap({ name: 'OTHER-EXPORT' }); + } + }); + Component.extend({ + tag: 'ref-export', + view: stache('{{*otherExport}}') + }); + var t1 = stache(''); + var f1 = t1(); + equal(canViewModel(f1.firstChild.firstChild).get('name'), 'OTHER-EXPORT', 'viewModel set correctly'); + equal(f1.firstChild.lastChild.nodeValue, 'OTHER-EXPORT', 'content'); + }); + runTestInOnlyDocument('custom renderer can provide setupBindings', function () { + var rendererFactory = function (tmpl) { + var frag = getFragment(tmpl); + return function (scope, options) { + scope = scope || new Scope(); + options = options || {}; + if (frag.firstChild.nodeName === 'CUSTOM-RENDERER') { + viewCallbacks.tagHandler(frag.firstChild, 'custom-renderer', { + scope: scope, + options: options, + templateType: 'my-renderer', + setupBindings: function (el, callback, data) { + callback({ foo: 'qux' }); + } + }); + } else { + var tn = frag.firstChild.firstChild; + tn.nodeValue = scope.read('foo').value; + } + return frag; + }; + }; + Component.extend({ + tag: 'custom-renderer', + view: rendererFactory('
    {{foo}}
    '), + ViewModel: SimpleMap.extend({}) + }); + var renderer = rendererFactory(''); + var frag = renderer(); + var tn = frag.firstChild.firstChild.firstChild; + equal(tn.nodeValue, 'qux', 'was bound!'); + }); + QUnit.test('view defaults to stache if set to a string', function () { + Component.extend({ + tag: 'hello-world', + leakScope: true, + view: '{{greeting}} World{{../exclamation}}', + viewModel: function () { + return new SimpleMap({ greeting: 'Hello' }); + } + }); + var renderer = stache(''); + var frag = renderer({ exclamation: '!' }); + var hello = frag.firstChild; + equal(hello.innerHTML.trim(), 'Hello World!'); + }); + QUnit.test('content tag available (#279)', function () { + var template = stache('CT-OUTER-LIGHT-DOM'); + Component.extend({ + tag: 'ct-outer', + view: 'CT-OUTER-SHADOW-START CT-OUTER-SHADOW-END' + }); + Component.extend({ + tag: 'ct-inner', + leakScope: true, + view: stache('') + }); + var frag = template(); + var span = frag.firstChild.getElementsByTagName('span')[0]; + QUnit.equal(span.innerHTML, 'CT-OUTER-LIGHT-DOM'); + }); + }); +}); +/*can-component@4.4.9#test/component-helpers-test*/ +define('can-component@4.4.9#test/component-helpers-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './helpers', + 'can-stache', + 'can-component' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var helpers = require('./helpers'); + var stache = require('can-stache'); + var Component = require('can-component'); + helpers.makeTests('can-component helpers', function () { + QUnit.test('helpers reference the correct instance (#515)', function () { + expect(2); + Component({ + tag: 'my-text', + view: stache('

    {{valueHelper()}}

    '), + helpers: { + valueHelper: function () { + return this.get('value'); + } + } + }); + var renderer = stache(''); + var frag = renderer({}); + equal(frag.firstChild.firstChild.firstChild.nodeValue, 'value1'); + equal(frag.lastChild.firstChild.firstChild.nodeValue, 'value2'); + }); + }); +}); +/*can-component@4.4.9#test/component-events-test*/ +define('can-component@4.4.9#test/component-events-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './helpers', + 'can-simple-map', + 'can-stache', + 'can-component', + 'can-view-model', + 'can-simple-observable', + 'can-dom-events', + 'can-dom-mutate/node', + 'can-dom-mutate/dom-events' +], function (require, exports, module) { + (function (global, require, exports, module) { + var QUnit = require('steal-qunit'); + var helpers = require('./helpers'); + var SimpleMap = require('can-simple-map'); + var stache = require('can-stache'); + var Component = require('can-component'); + var canViewModel = require('can-view-model'); + var SimpleObservable = require('can-simple-observable'); + var domEvents = require('can-dom-events'); + var domMutateNode = require('can-dom-mutate/node'); + var domMutateDomEvents = require('can-dom-mutate/dom-events'); + var insertedEvent = domMutateDomEvents.inserted; + var removedEvent = domMutateDomEvents.removed; + helpers.makeTests('can-component events', function () { + test('value observables formerly (#550)', function () { + var nameChanges = 0; + Component.extend({ + tag: 'viewmodel-rebinder', + events: { + '{name}': function () { + nameChanges++; + } + } + }); + var renderer = stache(''); + var frag = renderer(); + var viewModel = canViewModel(frag.firstChild); + var n1 = new SimpleObservable(), n2 = new SimpleObservable(); + viewModel.set('name', n1); + n1.set('updated'); + viewModel.set('name', n2); + n2.set('updated'); + equal(nameChanges, 2); + }); + test('Component events bind to window', function () { + window.tempMap = new SimpleMap(); + Component.extend({ + tag: 'window-events', + events: { + '{tempMap} prop': function () { + ok(true, 'called templated event'); + } + } + }); + var renderer = stache(''); + renderer(); + window.tempMap.set('prop', 'value'); + window.tempMap = undefined; + try { + delete window.tempMap; + } catch (e) { + } + }); + QUnit.test('stache conditionally nested components calls inserted once (#967)', function () { + expect(1); + var undo = domEvents.addEvent(insertedEvent); + Component.extend({ + tag: 'can-parent-stache', + viewModel: function () { + return new SimpleMap({ shown: true }); + }, + view: stache('{{#if shown}}{{/if}}') + }); + Component.extend({ + tag: 'can-child', + events: { + inserted: function () { + ok(true, 'called inserted once'); + } + } + }); + var renderer = stache(''); + domMutateNode.appendChild.call(this.fixture, renderer()); + stop(); + setTimeout(function () { + undo(); + start(); + }, 100); + }); + QUnit.test('viewModel objects with Constructor functions as properties do not get converted (#1261)', 1, function () { + stop(); + var HANDLER; + var Test = SimpleMap.extend({ + addEventListener: function (ev, handler) { + HANDLER = handler; + }, + removeEventListener: function () { + } + }, { + setup: function (props) { + props.test = 'Yeah'; + return SimpleMap.prototype.setup.apply(this, arguments); + } + }); + Component.extend({ + tag: 'my-app', + viewModel: SimpleMap.extend({ + setup: function (props) { + props.MyConstruct = Test; + return SimpleMap.prototype.setup.apply(this, arguments); + } + }), + events: { + '{MyConstruct} something': function () { + ok(true, 'Event got triggered'); + start(); + } + } + }); + var frag = stache('')(); + domMutateNode.appendChild.call(this.fixture, frag); + HANDLER.call(Test, { type: 'something' }); + }); + QUnit.test('removing bound viewModel properties on destroy #1415', function () { + var state = new SimpleMap({ + product: new SimpleMap({ + id: 1, + name: 'Tom' + }) + }); + Component.extend({ + tag: 'destroyable-component', + events: { + destroy: function () { + this.viewModel.set('product', null); + } + } + }); + var frag = stache('')(state); + domMutateNode.appendChild.call(this.fixture, frag); + domMutateNode.removeChild.call(this.fixture, this.fixture.firstChild); + stop(); + helpers.afterMutation(function () { + ok(state.attr('product') == null, 'product was removed'); + start(); + }); + }); + test('changing viewModel property rebinds {viewModel.<...>} events (#1529)', 2, function () { + Component.extend({ + tag: 'rebind-viewmodel', + events: { + init: function () { + this.viewModel.set('anItem', new SimpleMap({})); + }, + '{scope.anItem} name': function () { + ok(true, 'Change event on scope'); + }, + '{viewModel.anItem} name': function () { + ok(true, 'Change event on viewModel'); + } + } + }); + var frag = stache('')(); + var rebind = frag.firstChild; + domMutateNode.appendChild.call(this.fixture, rebind); + canViewModel(rebind).get('anItem').set('name', 'CDN'); + }); + QUnit.test('DOM trees not releasing when referencing CanMap inside CanMap in view (#1593)', function () { + var undo = domEvents.addEvent(removedEvent); + var baseTemplate = stache('{{#if show}}{{/if}}'), show = new SimpleObservable(true), state = new SimpleMap({ inner: 1 }); + var removeCount = 0; + Component.extend({ + tag: 'my-inside', + events: { + removed: function () { + removeCount++; + } + }, + leakScope: true + }); + Component.extend({ + tag: 'my-outside', + view: stache('{{#if ../state.inner}}{{/if}}'), + leakScope: true + }); + domMutateNode.appendChild.call(this.fixture, baseTemplate({ + show: show, + state: state + })); + helpers.runTasks([ + function () { + show.set(false); + }, + function () { + state.set('inner', null); + }, + function () { + equal(removeCount, 1, 'internal removed once'); + show.set(true); + }, + function () { + state.set('inner', 2); + }, + function () { + state.set('inner', null); + }, + function () { + equal(removeCount, 2, 'internal removed twice'); + undo(); + } + ]); + stop(); + }); + }); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-component@4.4.9#test/example-test*/ +define('can-component@4.4.9#test/example-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './helpers', + 'can-simple-map', + 'can-stache', + 'can-component', + 'can-define/list/list', + 'can-define/map/map', + 'can-dom-events', + 'can-view-model', + 'can-dom-mutate/node', + 'can-dom-mutate/dom-events', + 'can-log', + 'can-queues' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var helpers = require('./helpers'); + var SimpleMap = require('can-simple-map'); + var stache = require('can-stache'); + var Component = require('can-component'); + var DefineList = require('can-define/list/list'); + var DefineMap = require('can-define/map/map'); + var domEvents = require('can-dom-events'); + var canViewModel = require('can-view-model'); + var domMutateNode = require('can-dom-mutate/node'); + var domMutateDomEvents = require('can-dom-mutate/dom-events'); + var insertedEvent = domMutateDomEvents.inserted; + var canLog = require('can-log'); + var queues = require('can-queues'); + var innerHTML = function (el) { + return el && el.innerHTML; + }; + helpers.makeTests('can-component examples', function (doc) { + var Paginate = DefineMap.extend({ + count: { default: Infinity }, + offset: { default: 0 }, + limit: { default: 100 }, + setCount: function (newCount, success, error) { + return newCount < 0 ? 0 : newCount; + }, + setOffset: function (newOffset) { + return newOffset < 0 ? 0 : Math.min(newOffset, !isNaN(this.count - 1) ? this.count - 1 : Infinity); + }, + next: function () { + this.set('offset', this.offset + this.limit); + }, + prev: function () { + this.set('offset', this.offset - this.limit); + }, + canNext: function () { + return this.get('offset') < this.get('count') - this.get('limit'); + }, + canPrev: function () { + return this.get('offset') > 0; + }, + page: function (newVal) { + if (newVal === undefined) { + return Math.floor(this.get('offset') / this.get('limit')) + 1; + } else { + this.set('offset', (parseInt(newVal) - 1) * this.get('limit')); + } + }, + pageCount: function () { + return this.get('count') ? Math.ceil(this.get('count') / this.get('limit')) : null; + } + }); + test('treecombo', function () { + var TreeComboViewModel = DefineMap.extend('TreeComboViewModel', { + items: { Default: DefineList }, + breadcrumb: { Default: DefineList }, + selected: { Default: DefineList }, + selectableItems: function () { + var breadcrumb = this.get('breadcrumb'); + if (breadcrumb.length) { + return breadcrumb[breadcrumb.length - 1].children; + } else { + return this.get('items'); + } + }, + showChildren: function (item, ev) { + ev.stopPropagation(); + this.get('breadcrumb').push(item); + }, + emptyBreadcrumb: function () { + this.get('breadcrumb').update([]); + }, + updateBreadcrumb: function (item) { + var breadcrumb = this.get('breadcrumb'), index = breadcrumb.indexOf(item); + breadcrumb.splice(index + 1, breadcrumb.length - index - 1); + }, + toggle: function (item) { + var selected = this.get('selected'), index = selected.indexOf(item); + if (index === -1) { + selected.push(item); + } else { + selected.splice(index, 1); + } + }, + isSelected: function (item) { + return this.get('selected').indexOf(item) > -1; + } + }); + Component.extend({ + tag: 'treecombo', + view: stache('
      ' + '
    • {{title}}
    • ' + '{{#each breadcrumb}}' + '
    • {{title}}
    • ' + '{{/each}}' + '
    ' + '
      ' + '' + '{{#selectableItems()}}' + '
    • ' + '' + '{{title}}' + '{{#if children.length}}' + '' + '{{/if}}' + '
    • ' + '{{/selectableItems}}' + '
      ' + '
    '), + ViewModel: TreeComboViewModel + }); + var renderer = stache(''); + var BaseViewModel = DefineMap.extend('BaseViewModel', { seal: false }, {}); + var base = new BaseViewModel({}); + var frag = renderer(base); + var root = doc.createElement('div'); + root.appendChild(frag); + var items = [ + { + id: 1, + title: 'Midwest', + children: [ + { + id: 5, + title: 'Illinois', + children: [ + { + id: 23423, + title: 'Chicago' + }, + { + id: 4563, + title: 'Springfield' + }, + { + id: 4564, + title: 'Naperville' + } + ] + }, + { + id: 6, + title: 'Wisconsin', + children: [ + { + id: 232423, + title: 'Milwaulkee' + }, + { + id: 45463, + title: 'Green Bay' + }, + { + id: 45464, + title: 'Madison' + } + ] + } + ] + }, + { + id: 2, + title: 'East Coast', + children: [ + { + id: 25, + title: 'New York', + children: [ + { + id: 3413, + title: 'New York' + }, + { + id: 4613, + title: 'Rochester' + }, + { + id: 4516, + title: 'Syracuse' + } + ] + }, + { + id: 6, + title: 'Pennsylvania', + children: [ + { + id: 2362423, + title: 'Philadelphia' + }, + { + id: 454663, + title: 'Harrisburg' + }, + { + id: 454664, + title: 'Scranton' + } + ] + } + ] + } + ]; + stop(); + setTimeout(function () { + base.set('locations', items); + var itemsList = base.get('locations'); + var treecombo = root.firstChild, breadcrumb = treecombo.firstChild, breadcrumbLIs = function () { + return breadcrumb.getElementsByTagName('li'); + }, options = treecombo.lastChild, optionsLis = function () { + return options.getElementsByTagName('li'); + }; + equal(breadcrumbLIs().length, 1, 'Only the default title is shown'); + equal(breadcrumbLIs()[0].innerHTML, 'Locations', 'The correct title from the attribute is shown'); + equal(itemsList.length, optionsLis().length, 'first level items are displayed'); + domEvents.dispatch(optionsLis()[0], 'click'); + equal(optionsLis()[0].className, 'active', 'toggling something not selected adds active'); + ok(optionsLis()[0].getElementsByTagName('input')[0].checked, 'toggling something not selected checks checkbox'); + equal(canViewModel(treecombo, 'selected').length, 1, 'there is one selected item'); + equal(canViewModel(treecombo).selected[0], itemsList[0], 'the midwest is in selected'); + var selectedList = canViewModel(treecombo, 'selected'); + selectedList.pop(); + equal(optionsLis()[0].className, '', 'removing selected item in viewModel removes \'active\' class'); + domEvents.dispatch(optionsLis()[0].getElementsByTagName('button')[0], 'click'); + equal(breadcrumbLIs().length, 2, 'Only the default title is shown'); + equal(breadcrumbLIs()[1].innerHTML, 'Midwest', 'The breadcrumb has an item in it'); + ok(/Illinois/.test(optionsLis()[0].innerHTML), 'A child of the top breadcrumb is displayed'); + domEvents.dispatch(optionsLis()[0].getElementsByTagName('button')[0], 'click'); + ok(/Chicago/.test(optionsLis()[0].innerHTML), 'A child of the top breadcrumb is displayed'); + ok(!optionsLis()[0].getElementsByTagName('button').length, 'no show children button'); + domEvents.dispatch(breadcrumbLIs()[1], 'click'); + equal(innerHTML(breadcrumbLIs()[1]), 'Midwest', 'The breadcrumb has an item in it'); + ok(/Illinois/.test(innerHTML(optionsLis()[0])), 'A child of the top breadcrumb is displayed'); + domEvents.dispatch(breadcrumbLIs()[0], 'click'); + equal(breadcrumbLIs().length, 1, 'Only the default title is shown'); + equal(innerHTML(breadcrumbLIs()[0]), 'Locations', 'The correct title from the attribute is shown'); + start(); + }, 100); + }); + test('deferred grid', function () { + var GridViewModel = DefineMap.extend({ + items: { Default: DefineList }, + waiting: { default: true } + }); + Component.extend({ + tag: 'grid', + ViewModel: GridViewModel, + view: stache('
    '), + leakScope: true, + events: { + init: function () { + this.update(); + }, + '{viewModel} deferreddata': 'update', + update: function () { + var deferred = this.viewModel.get('deferreddata'), viewModel = this.viewModel; + if (deferred && deferred.then) { + this.viewModel.set('waiting', true); + deferred.then(function (items) { + viewModel.get('items').update(items); + }); + } else { + viewModel.get('items').update(deferred); + } + }, + '{items} length': function () { + this.viewModel.set('waiting', false); + } + } + }); + var SimulatedScope = DefineMap.extend({ + set: { default: 0 }, + deferredData: function () { + var deferred = {}; + var promise = new Promise(function (resolve, reject) { + deferred.resolve = resolve; + deferred.reject = reject; + }); + var set = this.get('set'); + if (set === 0) { + setTimeout(function () { + deferred.resolve([{ + first: 'Justin', + last: 'Meyer' + }]); + }, 100); + } else if (set === 1) { + setTimeout(function () { + deferred.resolve([{ + first: 'Brian', + last: 'Moschel' + }]); + }, 100); + } + return promise; + } + }); + var viewModel = new SimulatedScope(); + var renderer = stache('' + '{{#each items}}' + '' + '{{first}}' + '{{last}}' + '' + '{{/each}}' + ''); + domMutateNode.appendChild.call(this.fixture, renderer({ viewModel: viewModel })); + var gridScope = canViewModel(this.fixture.firstChild); + equal(gridScope.get('waiting'), true, 'The grid is initially waiting on the deferreddata to resolve'); + stop(); + var self = this; + var waitingHandler = function () { + gridScope.off('waiting', waitingHandler); + setTimeout(function () { + var tds = self.fixture.getElementsByTagName('td'); + equal(tds.length, 2, 'there are 2 tds'); + gridScope.on('waiting', function (ev, newVal) { + if (newVal === false) { + setTimeout(function () { + tds = self.fixture.getElementsByTagName('td'); + equal(innerHTML(tds[0]), 'Brian', 'td changed to brian'); + start(); + }, 100); + } + }); + viewModel.set = 1; + }, 100); + }; + gridScope.on('waiting', waitingHandler); + }); + test('nextprev', function () { + Component.extend({ + tag: 'next-prev', + view: stache('Prev' + 'Next') + }); + var paginator = new Paginate({ + limit: 20, + offset: 0, + count: 100 + }); + var renderer = stache(''); + var frag = renderer({ paginator: paginator }); + var nextPrev = frag.firstChild; + var prev = nextPrev.firstChild, next = nextPrev.lastChild; + ok(!/enabled/.test(prev.className), 'prev is not enabled'); + ok(/enabled/.test(next.className), 'next is enabled'); + domEvents.dispatch(next, 'click'); + ok(/enabled/.test(prev.getAttribute('class')), 'prev is enabled'); + }); + test('page-count', function () { + Component.extend({ + tag: 'page-count', + view: stache('Page {{page()}}.') + }); + var paginator = new Paginate({ + limit: 20, + offset: 0, + count: 100 + }); + var renderer = stache(''); + var frag = renderer(new SimpleMap({ paginator: paginator })); + var span = frag.firstChild.getElementsByTagName('span')[0]; + equal(span.firstChild.nodeValue, '1'); + paginator.next(); + equal(span.firstChild.nodeValue, '2'); + paginator.next(); + equal(span.firstChild.nodeValue, '3'); + }); + if (System.env !== 'canjs-test') { + QUnit.test('basic tabs', function () { + var undo = domEvents.addEvent(insertedEvent); + var TabsViewModel = DefineMap.extend({ + active: 'any', + panels: { Default: DefineList }, + addPanel: function (panel) { + if (this.panels.length === 0) { + this.makeActive(panel); + } + this.panels.push(panel); + }, + removePanel: function (panel) { + var panels = this.panels; + queues.batch.start(); + var index = panels.indexOf(panel); + canLog.log(index); + panels.splice(index, 1); + if (panel === this.active) { + if (panels.length) { + this.makeActive(panels[0]); + } else { + this.active = null; + } + } + queues.batch.stop(); + }, + makeActive: function (panel) { + this.active = panel; + this.panels.forEach(function (panel) { + panel.active = false; + }); + panel.active = true; + }, + isActive: function (panel) { + return this.active === panel; + } + }); + Component.extend({ + tag: 'tabs', + ViewModel: TabsViewModel, + view: stache('
      ' + '{{#panels}}' + '
    • {{title}}
    • ' + '{{/panels}}' + '
    ' + '') + }); + Component.extend({ + view: stache('{{#if active}}{{/if}}'), + tag: 'panel', + ViewModel: DefineMap.extend({ active: { default: false } }), + events: { + ' inserted': function () { + canViewModel(this.element.parentNode).addPanel(this.viewModel); + }, + ' beforeremove': function () { + canViewModel(this.element.parentNode).removePanel(this.viewModel); + } + } + }); + var renderer = stache('{{#each foodTypes}}{{content}}{{/each}}'); + var foodTypes = new DefineList([ + { + title: 'Fruits', + content: 'oranges, apples' + }, + { + title: 'Breads', + content: 'pasta, cereal' + }, + { + title: 'Sweets', + content: 'ice cream, candy' + } + ]); + var frag = renderer({ foodTypes: foodTypes }); + domMutateNode.appendChild.call(this.fixture, frag); + var testArea = this.fixture; + stop(); + helpers.runTasks([ + function () { + var lis = testArea.getElementsByTagName('li'); + equal(lis.length, 3, 'three lis added'); + foodTypes.forEach(function (type, i) { + equal(innerHTML(lis[i]), type.title, 'li ' + i + ' has the right content'); + }); + foodTypes.push({ + title: 'Vegies', + content: 'carrots, kale' + }); + }, + function () { + var lis = testArea.getElementsByTagName('li'); + equal(lis.length, 4, 'li added'); + foodTypes.forEach(function (type, i) { + equal(innerHTML(lis[i]), type.title, 'li ' + i + ' has the right content'); + }); + equal(testArea.getElementsByTagName('panel').length, 4, 'panel added'); + canLog.log('SHIFTY'); + foodTypes.shift(); + }, + function () { + var lis = testArea.getElementsByTagName('li'); + equal(lis.length, 3, 'removed li after shifting a foodType'); + foodTypes.forEach(function (type, i) { + equal(innerHTML(lis[i]), type.title, 'li ' + i + ' has the right content'); + }); + var panels = testArea.getElementsByTagName('panel'); + equal(lis[0].className, 'active', 'the first element is active'); + equal(innerHTML(panels[0]), 'pasta, cereal', 'the first content is shown'); + equal(innerHTML(panels[1]), '', 'the second content is removed'); + domEvents.dispatch(lis[1], 'click'); + lis = testArea.getElementsByTagName('li'); + equal(lis[1].className, 'active', 'the second element is active'); + equal(lis[0].className, '', 'the first element is not active'); + equal(innerHTML(panels[0]), '', 'the second content is removed'); + equal(innerHTML(panels[1]), 'ice cream, candy', 'the second content is shown'); + undo(); + } + ]); + }); + } + }); +}); +/*can-component@4.4.9#test/component-slot-test*/ +define('can-component@4.4.9#test/component-slot-test', [ + 'require', + 'exports', + 'module', + 'can-component', + 'can-stache', + 'steal-qunit', + 'can-define/map/map', + 'can-view-model', + 'can-symbol' +], function (require, exports, module) { + var Component = require('can-component'); + var stache = require('can-stache'); + var QUnit = require('steal-qunit'); + var DefineMap = require('can-define/map/map'); + var viewModel = require('can-view-model'); + var canSymbol = require('can-symbol'); + QUnit.module('can-components - can-slots'); + test(' Works', function () { + var ViewModel = DefineMap.extend({ + subject: { default: 'Hello World' }, + body: { default: 'Later Gator' } + }); + Component.extend({ + tag: 'my-email', + view: stache('' + ''), + ViewModel: ViewModel, + leakScope: true + }); + var renderer = stache('' + '' + '{{subject}}' + '' + '' + '{{body}}' + '' + ''); + var testView = renderer(); + equal(testView.firstChild.childNodes[0].nodeValue, 'Hello World'); + equal(testView.firstChild.childNodes[1].nodeValue, 'Later Gator'); + }); + test(' leakScope false acts as expected', function () { + var ViewModel = DefineMap.extend({ + subject: { default: 'Hello World' }, + body: { default: 'Later Gator' } + }); + Component.extend({ + tag: 'my-email', + view: stache('' + ''), + ViewModel: ViewModel + }); + var renderer = stache('' + '' + '{{subject}}' + '' + '' + '{{body}}' + '' + ''); + var testView = renderer({ + subject: 'foo', + body: 'bar' + }); + equal(testView.firstChild.childNodes[0].nodeValue, 'foo'); + equal(testView.firstChild.childNodes[1].nodeValue, 'bar'); + }); + test(' Re-use templates', function () { + var ViewModel = DefineMap.extend({ + subject: { default: 'Hello World' }, + body: { default: 'Later Gator' } + }); + Component.extend({ + tag: 'my-email', + view: stache('' + ''), + ViewModel: ViewModel, + leakScope: true + }); + var renderer = stache('' + '' + '{{subject}}' + '' + ''); + var testView = renderer(); + equal(testView.firstChild.childNodes[0].nodeValue, 'Hello World'); + equal(testView.firstChild.childNodes[1].nodeValue, 'Hello World'); + }); + test(' Works with default content', function () { + var ViewModel = DefineMap.extend({}); + Component.extend({ + tag: 'my-email', + view: stache('' + 'Default Content' + ''), + ViewModel: ViewModel + }); + var renderer = stache('' + '' + ''); + var testView = renderer(); + equal(testView.firstChild.innerHTML, 'Default Content'); + }); + test(' Works in a self-closing template', function () { + var ViewModel = DefineMap.extend({}); + Component.extend({ + tag: 'my-email', + view: stache('' + 'Default Content' + ''), + ViewModel: ViewModel + }); + var renderer = stache(''); + var testView = renderer(); + equal(testView.firstChild.innerHTML, 'Default Content'); + }); + test(' Context one-way binding works', function () { + var ViewModel = DefineMap.extend('MyEmailVM', { subject: { default: 'Hello World' } }); + Component.extend({ + tag: 'my-email', + view: stache(''), + ViewModel: ViewModel + }); + var renderer = stache('' + '{{this}}' + ''); + var frag = renderer(); + var vm = viewModel(frag.firstChild); + equal(frag.firstChild.firstChild.innerHTML, 'Hello World'); + vm.subject = 'Later Gator'; + equal(frag.firstChild.firstChild.innerHTML, 'Later Gator'); + }); + test(' Context two-way binding works', function () { + var ViewModel = DefineMap.extend('MyEmailVM', {}, { subject: { default: 'Hello World' } }); + Component.extend({ + tag: 'my-email', + view: stache(''), + ViewModel: ViewModel + }); + Component.extend({ + tag: 'my-subject', + view: stache('{{subject}}'), + ViewModel: DefineMap.extend('SubjectVM') + }); + var renderer = stache('' + '' + ''); + var frag = renderer(); + var vm = viewModel(frag.firstChild); + var childVM = viewModel(frag.firstChild.firstChild); + equal(frag.firstChild.firstChild.innerHTML, 'Hello World'); + vm.subject = 'Later Gator'; + equal(frag.firstChild.firstChild.innerHTML, 'Later Gator'); + childVM.subject = 'After a while crocodile'; + equal(vm.subject, 'After a while crocodile'); + }); + test(' Context child-to-parent binding works', function () { + var ViewModel = DefineMap.extend({ subject: { default: 'Hello World' } }); + Component.extend({ + tag: 'my-email', + view: stache(''), + ViewModel: ViewModel + }); + Component.extend({ + tag: 'my-subject', + view: stache('{{subject}}'), + ViewModel: DefineMap.extend({ subject: { default: 'Yo' } }) + }); + var renderer = stache('' + '' + ''); + var frag = renderer(); + var vm = viewModel(frag.firstChild); + var childVM = viewModel(frag.firstChild.firstChild); + equal(frag.firstChild.firstChild.innerHTML, 'Yo'); + childVM.subject = 'bar'; + equal(frag.firstChild.firstChild.innerHTML, 'bar'); + equal(vm.subject, 'bar'); + }); + test(' Works alongside ', function () { + var ViewModel = DefineMap.extend({ + subject: { default: 'Hello World' }, + body: { default: 'Later Gator' } + }); + Component.extend({ + tag: 'my-email', + view: stache('' + ''), + ViewModel: ViewModel, + leakScope: true + }); + var renderer = stache('' + '' + '

    {{subject}}

    ' + '
    ' + 'Some content' + '
    '); + var testView = renderer(); + equal(testView.firstChild.childNodes[0].firstChild.nodeValue, 'Hello World'); + equal(testView.firstChild.childNodes[1].firstChild.nodeValue, 'Some content'); + }); + test(' Works alongside with default content', function () { + var ViewModel = DefineMap.extend({ + subject: { default: 'Hello World' }, + body: { default: 'Later Gator' } + }); + Component.extend({ + tag: 'my-email', + view: stache('' + 'Default content'), + ViewModel: ViewModel, + leakScope: true + }); + var renderer = stache('' + '' + '

    {{subject}}

    ' + '
    ' + '
    '); + var testView = renderer(); + equal(testView.firstChild.childNodes[0].firstChild.nodeValue, 'Hello World'); + equal(testView.firstChild.childNodes[1].nodeValue, 'Default content'); + }); + test(' Can be used conditionally and will remove bindings', function () { + var ViewModel = DefineMap.extend('MyEmailVM', { + subject: { default: 'Hello World' }, + showSubject: { default: true } + }); + Component.extend({ + tag: 'my-email', + view: stache('{{#if showSubject}}{{/if}}'), + ViewModel: ViewModel + }); + var renderer = stache('' + '' + '

    {{this}}

    ' + '
    ' + '
    '); + var testView = renderer(); + equal(testView.firstChild.firstChild.firstChild.nodeValue, 'Hello World'); + var vm = viewModel(testView.firstChild); + vm.showSubject = false; + QUnit.stop(); + QUnit.equal(testView.firstChild.children.length, 0); + setTimeout(function () { + var handlers = vm[canSymbol.for('can.meta')].handlers; + QUnit.equal(handlers.get(['subject']).length, 0); + QUnit.start(); + }, 50); + }); + test('blocks directly nested within template', function () { + var template = stache('' + '' + '{{#if(showIf)}}' + '.showIf is true' + '{{else}}' + '.showIf is false' + '{{/if}}' + '' + ''); + var viewModel = new DefineMap({ + showSlot: true, + showIf: true + }); + Component.extend({ + tag: 'home-page', + view: stache('{{#if(showSlot)}}' + '' + '{{/if}}'), + viewModel: viewModel + }); + var frag = template(); + var homePage = frag.firstChild; + viewModel.showIf = false; + viewModel.showSlot = false; + var spans = homePage.getElementsByTagName('span'); + QUnit.equal(spans.length, 0, 'all spans removed'); + }); + QUnit.test('able to pass individual values (#291)', function () { + Component.extend({ + tag: 'pass-values-to-slots', + view: '', + ViewModel: { + count: { + type: 'number', + default: 0 + }, + add: function (increment) { + this.count += increment; + } + } + }); + var template = stache('' + '' + '{{count}}' + '' + ''); + var frag = template(); + var passValuesToSlots = frag.firstElementChild || frag.firstChild; + passValuesToSlots.viewModel.add(5); + var count = passValuesToSlots.querySelector('.count'); + QUnit.equal(count.innerHTML, '10', 'updated count value'); + }); +}); +/*can-util@3.14.0#js/is-array-like/is-array-like*/ +define('can-util@3.14.0#js/is-array-like/is-array-like', [ + 'require', + 'exports', + 'module', + 'can-namespace' +], function (require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + function isArrayLike(obj) { + var type = typeof obj; + if (type === 'string') { + return true; + } else if (type === 'number') { + return false; + } + var length = obj && type !== 'boolean' && typeof obj !== 'number' && 'length' in obj && obj.length; + return typeof obj !== 'function' && (length === 0 || typeof length === 'number' && length > 0 && length - 1 in obj); + } + module.exports = namespace.isArrayLike = isArrayLike; +}); +/*can-util@3.14.0#js/is-iterable/is-iterable*/ +define('can-util@3.14.0#js/is-iterable/is-iterable', [ + 'require', + 'exports', + 'module', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var canSymbol = require('can-symbol'); + module.exports = function (obj) { + return obj && !!obj[canSymbol.iterator || canSymbol.for('iterator')]; + }; +}); +/*can-util@3.14.0#js/each/each*/ +define('can-util@3.14.0#js/each/each', [ + 'require', + 'exports', + 'module', + '../is-array-like/is-array-like', + '../is-iterable/is-iterable', + 'can-symbol', + 'can-namespace' +], function (require, exports, module) { + 'use strict'; + var isArrayLike = require('../is-array-like/is-array-like'); + var has = Object.prototype.hasOwnProperty; + var isIterable = require('../is-iterable/is-iterable'); + var canSymbol = require('can-symbol'); + var namespace = require('can-namespace'); + function each(elements, callback, context) { + var i = 0, key, len, item; + if (elements) { + if (isArrayLike(elements)) { + for (len = elements.length; i < len; i++) { + item = elements[i]; + if (callback.call(context || item, item, i, elements) === false) { + break; + } + } + } else if (isIterable(elements)) { + var iter = elements[canSymbol.iterator || canSymbol.for('iterator')](); + var res, value; + while (!(res = iter.next()).done) { + value = res.value; + callback.call(context || elements, Array.isArray(value) ? value[1] : value, value[0]); + } + } else if (typeof elements === 'object') { + for (key in elements) { + if (has.call(elements, key) && callback.call(context || elements[key], elements[key], key, elements) === false) { + break; + } + } + } + } + return elements; + } + module.exports = namespace.each = each; +}); +/*can-util@3.14.0#js/make-array/make-array*/ +define('can-util@3.14.0#js/make-array/make-array', [ + 'require', + 'exports', + 'module', + '../each/each', + '../is-array-like/is-array-like', + 'can-namespace' +], function (require, exports, module) { + 'use strict'; + var each = require('../each/each'); + var isArrayLike = require('../is-array-like/is-array-like'); + var namespace = require('can-namespace'); + function makeArray(element) { + var ret = []; + if (isArrayLike(element)) { + each(element, function (a, i) { + ret[i] = a; + }); + } else if (element === 0 || element) { + ret.push(element); + } + return ret; + } + module.exports = namespace.makeArray = makeArray; +}); +/*can-util@3.14.0#js/global/global*/ +define('can-util@3.14.0#js/global/global', [ + 'require', + 'exports', + 'module', + 'can-namespace', + 'can-globals/global/global' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + module.exports = namespace.global = require('can-globals/global/global'); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-test-helpers@1.1.2#lib/dev*/ +define('can-test-helpers@1.1.2#lib/dev', [ + 'require', + 'exports', + 'module', + 'can-log/dev/dev', + 'can-util/js/make-array/make-array', + 'can-util/js/global/global' +], function (require, exports, module) { + (function (global, require, exports, module) { + var dev = require('can-log/dev/dev'); + var makeArray = require('can-util/js/make-array/make-array'); + var GLOBAL = require('can-util/js/global/global'); + function makeExpectation(type) { + var original; + var expectedResults = []; + function stubbed() { + var message = makeArray(arguments).map(function (token) { + if (typeof token !== 'string' && token.message) { + return token.message; + } else { + return token; + } + }).join(' '); + expectedResults.forEach(function (expected) { + var matched = typeof expected.source === 'string' ? message === expected.source : expected.source.test(message); + if (matched) { + expected.count++; + } + if (typeof expected.fn === 'function') { + expected.fn.call(null, message, matched); + } + }); + } + return function (expected, fn) { + var matchData = { + source: expected, + fn: fn, + count: 0 + }; + expectedResults.push(matchData); + if (!original) { + original = dev[type]; + dev[type] = stubbed; + } + return function () { + expectedResults.splice(expectedResults.indexOf(matchData), 1); + if (original && expectedResults.length < 1) { + dev[type] = original; + original = null; + } + return matchData.count; + }; + }; + } + module.exports = { + willWarn: makeExpectation('warn'), + willError: makeExpectation('error'), + devOnlyTest: function () { + var global = GLOBAL(); + if (!global.System || !global.System.env || global.System.env.indexOf('production') < 0) { + global.test.apply(null, arguments); + } + } + }; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-test-helpers@1.1.2#can-test-helpers*/ +define('can-test-helpers@1.1.2#can-test-helpers', [ + 'require', + 'exports', + 'module', + 'can-test-helpers/lib/dev' +], function (require, exports, module) { + var dev = require('can-test-helpers/lib/dev'); + module.exports = { dev: dev }; +}); +/*can-component@4.4.9#test/component-define-test*/ +define('can-component@4.4.9#test/component-define-test', [ + 'require', + 'exports', + 'module', + 'can-component', + 'can-stache', + 'steal-qunit', + 'can-define', + 'can-define/map/map', + 'can-view-model', + 'can-log/dev/dev', + 'can-test-helpers' +], function (require, exports, module) { + var Component = require('can-component'); + var stache = require('can-stache'); + var QUnit = require('steal-qunit'); + var define = require('can-define'); + var DefineMap = require('can-define/map/map'); + var viewModel = require('can-view-model'); + var canDev = require('can-log/dev/dev'); + var testHelpers = require('can-test-helpers'); + QUnit.module('can-component with can-define'); + QUnit.test('Works with can-define', function () { + var VM = define.Constructor({ + firstName: { type: 'string' }, + lastName: { type: 'string' }, + fullName: { + get: function () { + return [ + this.firstName, + this.lastName + ].join(' '); + } + } + }); + Component.extend({ + tag: 'can-define-component', + ViewModel: VM, + view: stache('Name: {{fullName}}') + }); + var frag = stache('')({ + firstName: 'Chris', + lastName: 'Gomez' + }); + var vm = viewModel(frag.firstChild); + QUnit.ok(vm instanceof VM, 'Constructor was called'); + QUnit.equal(vm.firstName, 'Chris', 'ViewModel was set from scope'); + QUnit.equal(vm.lastName, 'Gomez', 'ViewModel was set from scope'); + QUnit.equal(frag.firstChild.innerHTML, 'Name: Chris Gomez', 'Rendered fullName'); + vm.firstName = 'Justin'; + vm.lastName = 'Meyer'; + QUnit.equal(frag.firstChild.innerHTML, 'Name: Justin Meyer', 'Rendered fullName after change'); + }); + QUnit.test('scope method works', function () { + Component.extend({ + tag: 'my-element', + viewModel: function (properties, scope, element) { + QUnit.deepEqual(properties, { + first: 'Justin', + last: 'Meyer' + }); + return new DefineMap(properties); + } + }); + stache('')({ + firstName: 'Justin', + middleName: 'Barry' + }); + }); + QUnit.test('33 - works when instantiated with an object for ViewModel', function () { + Component.extend({ + tag: 'test-element', + view: stache('{{someMethod()}}'), + ViewModel: { + someMethod: function () { + ok(true, 'Function got called'); + return true; + } + } + }); + var renderer = stache(''); + renderer(); + }); + QUnit.test('helpers do not leak when leakscope is false (#77)', function () { + var called = 0; + Component.extend({ + tag: 'inner-el', + view: stache('inner{{test}}'), + leakScope: false + }); + Component.extend({ + tag: 'outer-el', + view: stache('outer:'), + helpers: { + test: function () { + called++; + return 'heyo'; + } + } + }); + var renderer = stache(''); + renderer(); + QUnit.equal(called, 0, 'Outer helper not called'); + }); + QUnit.test('helpers do leak when leakscope is true (#77)', function () { + var called = 0; + Component.extend({ + tag: 'inner-el', + view: stache('inner{{../test()}}'), + leakScope: true + }); + Component.extend({ + tag: 'outer-el', + view: stache('outer:'), + helpers: { + test: function () { + called++; + return 'heyo'; + } + } + }); + var renderer = stache(''); + renderer(); + QUnit.equal(called, 1, 'Outer helper called once'); + }); + if (System.env.indexOf('production') < 0) { + QUnit.test('warn if viewModel is assigned a DefineMap (#14)', function () { + QUnit.expect(1); + var oldwarn = canDev.warn; + canDev.warn = function (mesg) { + QUnit.equal(mesg, 'can-component: Assigning a DefineMap or constructor type to the viewModel property may not be what you intended. Did you mean ViewModel instead? More info: https://canjs.com/doc/can-component.prototype.ViewModel.html', 'Warning is expected message'); + }; + var VM = DefineMap.extend({}); + Component.extend({ + tag: 'can-vm1-test-component', + viewModel: VM + }); + Component.extend({ + tag: 'can-vm2-test-component', + viewModel: function () { + } + }); + canDev.warn = oldwarn; + }); + } + QUnit.test('ViewModel defaults to DefineMap if set to an Object', function () { + Component.extend({ + tag: 'can-define-component', + ViewModel: { + firstName: { type: 'string' }, + lastName: { type: 'string' }, + fullName: { + get: function () { + return [ + this.firstName, + this.lastName + ].join(' '); + } + } + }, + view: stache('Name: {{fullName}}') + }); + var frag = stache('')({ + firstName: 'Chris', + lastName: 'Gomez' + }); + var vm = viewModel(frag.firstChild); + QUnit.ok(vm instanceof DefineMap, 'vm is a DefineMap'); + QUnit.equal(vm.firstName, 'Chris', 'ViewModel was set from scope'); + QUnit.equal(vm.lastName, 'Gomez', 'ViewModel was set from scope'); + QUnit.equal(frag.firstChild.innerHTML, 'Name: Chris Gomez', 'Rendered fullName'); + vm.firstName = 'Justin'; + vm.lastName = 'Meyer'; + QUnit.equal(frag.firstChild.innerHTML, 'Name: Justin Meyer', 'Rendered fullName after change'); + }); + QUnit.test('ViewModel properties default to DefineList if set to an Array (#225)', function () { + Component.extend({ + tag: 'viewmodel-lists', + view: 'Hello, World', + ViewModel: { + items: { + default: function () { + return [ + 'one', + 'two' + ]; + } + } + } + }); + var renderer = stache(''); + var fragOne = renderer(); + var vm = viewModel(fragOne.firstChild); + QUnit.ok(vm.items instanceof define.DefineList, 'vm is a DefineList'); + }); + testHelpers.dev.devOnlyTest('filename should be passed to stache() for inline views', function () { + Component.extend({ + tag: 'my-filename-component', + ViewModel: {}, + view: '{{scope.filename}}' + }); + var renderer = stache(''); + var frag = renderer(); + QUnit.equal(frag.firstChild.innerHTML, 'MyFilenameComponentView', 'filename was provided to stache()'); + }); +}); +/*can-key@1.2.0#delete/delete*/ +define('can-key@1.2.0#delete/delete', [ + 'require', + 'exports', + 'module', + 'can-reflect', + '../utils' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var utils = require('../utils'); + module.exports = function deleteAtPath(data, path) { + var parts = utils.parts(path); + var current = data; + for (var i = 0; i < parts.length - 1; i++) { + if (current) { + current = canReflect.getKeyValue(current, parts[i]); + } + } + if (current) { + canReflect.deleteKeyValue(current, parts[parts.length - 1]); + } + }; +}); +/*can-key@1.2.0#replace-with/replace-with*/ +define('can-key@1.2.0#replace-with/replace-with', [ + 'require', + 'exports', + 'module', + '../utils', + '../get/get', + '../delete/delete' +], function (require, exports, module) { + 'use strict'; + var utils = require('../utils'); + var get = require('../get/get'); + var deleteKey = require('../delete/delete'); + module.exports = function (str, data, replacer, shouldRemoveMatchedPaths) { + return str.replace(utils.strReplacer, function (whole, path) { + var value = get(data, path); + if (shouldRemoveMatchedPaths) { + deleteKey(data, path); + } + return replacer ? replacer(path, value) : value; + }); + }; +}); +/*can-key@1.2.0#set/set*/ +define('can-key@1.2.0#set/set', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-symbol', + '../utils' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var utils = require('../utils'); + var setValueSymbol = canSymbol.for('can.setValue'); + function set(object, path, value) { + var parts = utils.parts(path); + var current = object; + var length = parts.length; + for (var i = 0; i < length - 1; i++) { + if (utils.isContainer(current)) { + current = canReflect.getKeyValue(current, parts[i]); + } else { + break; + } + } + if (current) { + canReflect.setKeyValue(current, parts[i], value); + } else { + throw new TypeError('Cannot set value at key path \'' + path + '\''); + } + return object; + } + module.exports = set; +}); +/*can-key@1.2.0#walk/walk*/ +define('can-key@1.2.0#walk/walk', [ + 'require', + 'exports', + 'module', + 'can-reflect', + '../utils' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var utils = require('../utils'); + module.exports = function walk(obj, name, keyCallback) { + var parts = utils.parts(name); + var length = parts.length, current, i, container, part; + if (!length) { + return; + } + current = obj; + for (i = 0; i < length; i++) { + container = current; + part = parts[i]; + current = utils.isContainer(container) && canReflect.getKeyValue(container, part); + var result = keyCallback({ + parent: container, + key: part, + value: current + }, i); + if (result !== undefined) { + current = result; + } + } + }; +}); +/*can-key@1.2.0#transform/transform*/ +define('can-key@1.2.0#transform/transform', [ + 'require', + 'exports', + 'module', + '../walk/walk', + '../utils', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var walk = require('../walk/walk'); + var utils = require('../utils'); + var canReflect = require('can-reflect'); + function deleteKeys(parentsAndKeys) { + for (var i = parentsAndKeys.length - 1; i >= 0; i--) { + var parentAndKey = parentsAndKeys[i]; + delete parentAndKey.parent[parentAndKey.key]; + if (canReflect.size(parentAndKey.parent) !== 0) { + return; + } + } + } + module.exports = function (obj, transformer) { + var copy = canReflect.serialize(obj); + canReflect.eachKey(transformer, function (writeKey, readKey) { + var readParts = utils.parts(readKey), writeParts = utils.parts(writeKey); + var parentsAndKeys = []; + walk(copy, readParts, function (info) { + parentsAndKeys.push(info); + }); + var last = parentsAndKeys[parentsAndKeys.length - 1]; + var value = last.value; + if (value !== undefined) { + walk(copy, writeParts, function (info, i) { + if (i < writeParts.length - 1 && !info.value) { + return info.parent[info.key] = {}; + } else if (i === writeParts.length - 1) { + info.parent[info.key] = value; + } + }); + deleteKeys(parentsAndKeys); + } + }); + return copy; + }; +}); +/*can-key@1.2.0#can-key*/ +define('can-key@1.2.0#can-key', [ + 'require', + 'exports', + 'module', + 'can-key/delete/delete', + 'can-key/get/get', + 'can-key/replace-with/replace-with', + 'can-key/set/set', + 'can-key/transform/transform', + 'can-key/walk/walk', + 'can-namespace' +], function (require, exports, module) { + 'use strict'; + var deleteKey = require('can-key/delete/delete'), get = require('can-key/get/get'), replaceWith = require('can-key/replace-with/replace-with'), set = require('can-key/set/set'), transform = require('can-key/transform/transform'), walk = require('can-key/walk/walk'), namespace = require('can-namespace'); + module.exports = namespace.key = { + deleteKey: deleteKey, + get: get, + replaceWith: replaceWith, + set: set, + transform: transform, + walk: walk + }; +}); +/*can-simple-observable@2.4.1#key/key*/ +define('can-simple-observable@2.4.1#key/key', [ + 'require', + 'exports', + 'module', + 'can-key', + 'can-key/utils', + 'can-reflect', + 'can-observation' +], function (require, exports, module) { + var canKey = require('can-key'); + var canKeyUtils = require('can-key/utils'); + var canReflect = require('can-reflect'); + var Observation = require('can-observation'); + module.exports = function keyObservable(root, keyPath) { + var keyPathParts = canKeyUtils.parts(keyPath); + var lastIndex = keyPathParts.length - 1; + var observation = new Observation(function () { + var value; + canKey.walk(root, keyPathParts, function (keyData, i) { + if (i === lastIndex) { + value = keyData.value; + } + }); + return value; + }); + var valueSetter = function (newVal) { + canKey.set(root, keyPathParts, newVal); + }; + Object.defineProperty(observation, 'value', { + get: observation.get, + set: valueSetter + }); + var symbolsToAssign = { 'can.setValue': valueSetter }; + return canReflect.assignSymbols(observation, symbolsToAssign); + }; +}); +/*can-value@1.1.0#can-value*/ +define('can-value@1.1.0#can-value', [ + 'require', + 'exports', + 'module', + 'can-key', + 'can-reflect', + 'can-simple-observable/key/key', + 'can-namespace', + 'can-observation', + 'can-simple-observable', + 'can-simple-observable/settable/settable' +], function (require, exports, module) { + 'use strict'; + var canKey = require('can-key'); + var canReflect = require('can-reflect'); + var keyObservable = require('can-simple-observable/key/key'); + var namespace = require('can-namespace'); + var Observation = require('can-observation'); + var SimpleObservable = require('can-simple-observable'); + var SettableObservable = require('can-simple-observable/settable/settable'); + module.exports = namespace.value = { + bind: function (object, keyPath) { + return keyObservable(object, keyPath); + }, + from: function (object, keyPath) { + var observationFunction = function () { + return canKey.get(object, keyPath); + }; + return new Observation(observationFunction); + }, + returnedBy: function (getter, context, initialValue) { + if (getter.length === 1) { + return new SettableObservable(getter, context, initialValue); + } else { + return new Observation(getter, context); + } + }, + to: function (object, keyPath) { + var observable = keyObservable(object, keyPath); + var symbolsToAssign = { 'can.getValue': null }; + return canReflect.assignSymbols(observable, symbolsToAssign); + }, + with: function (initialValue) { + return new SimpleObservable(initialValue); + } + }; +}); +/*can-component@4.4.9#test/component-instantiation-test*/ +define('can-component@4.4.9#test/component-instantiation-test', [ + 'require', + 'exports', + 'module', + 'can-component', + 'can-define/map/map', + 'steal-qunit', + 'can-simple-map', + 'can-stache', + 'can-value' +], function (require, exports, module) { + var Component = require('can-component'); + var DefineMap = require('can-define/map/map'); + var QUnit = require('steal-qunit'); + var SimpleMap = require('can-simple-map'); + var stache = require('can-stache'); + var value = require('can-value'); + QUnit.module('can-component instantiation'); + QUnit.test('Components can be instantiated with new', function () { + var ComponentConstructor = Component.extend({ + tag: 'new-instantiation', + view: 'Hello {{message}}', + ViewModel: { message: 'string' } + }); + var componentInstance = new ComponentConstructor(); + var element = componentInstance.element; + var viewModel = componentInstance.viewModel; + QUnit.ok(element, 'instance has element property'); + QUnit.equal(element.textContent, 'Hello ', 'element has correct text content'); + QUnit.ok(viewModel, 'instance has viewModel property'); + viewModel.message = 'world'; + QUnit.equal(element.textContent, 'Hello world', 'element has correct text content after updating viewModel'); + }); + QUnit.test('Components can be instantiated with - no scope', function () { + var ComponentConstructor = Component.extend({ + tag: 'new-instantiation-content-no-scope', + view: 'Hello {{message}}', + ViewModel: { message: { default: 'world' } } + }); + var componentInstance = new ComponentConstructor({ content: stache('mundo') }); + var element = componentInstance.element; + QUnit.equal(element.innerHTML, 'Hello mundo', 'content is rendered'); + }); + QUnit.test('Components can be instantiated with - with plain content and scope', function () { + var ComponentConstructor = Component.extend({ + tag: 'new-instantiation-plain-content-and-scope', + view: 'Hello {{message}}', + ViewModel: { message: { default: 'world' } } + }); + var componentInstance = new ComponentConstructor({ + content: '{{message}}', + scope: { message: 'mundo' } + }); + var element = componentInstance.element; + QUnit.equal(element.innerHTML, 'Hello mundo', 'content is rendered'); + }); + QUnit.test('Components can be instantiated with - with scope - leakScope false', function () { + var ComponentConstructor = Component.extend({ + leakScope: false, + tag: 'new-instantiation-content-leakscope-false', + view: 'Hello {{message}}', + ViewModel: { message: { default: 'world' } } + }); + var scopeVM = new DefineMap({}); + var componentInstance = new ComponentConstructor({ + content: '{{message}}', + scope: scopeVM + }); + var element = componentInstance.element; + QUnit.equal(element.innerHTML, 'Hello ', 'content is rendered with the provided scope'); + scopeVM.set('message', 'mundo'); + QUnit.equal(element.innerHTML, 'Hello mundo', 'content updates with the provided scope'); + }); + QUnit.test('Components can be instantiated with - with scope - leakScope true', function () { + var ComponentConstructor = Component.extend({ + leakScope: true, + tag: 'new-instantiation-content-leakscope-true', + view: 'Hello {{message}}', + ViewModel: { message: { default: 'world' } } + }); + var componentInstance = new ComponentConstructor({ + content: '{{scope.find(\'message\')}}', + scope: { message: 'mundo' } + }); + var element = componentInstance.element; + QUnit.equal(element.innerHTML, 'Hello world', 'content is rendered with the component\u2019s scope'); + }); + QUnit.test('Components can be instantiated with templates', function () { + var ComponentConstructor = Component.extend({ + tag: 'new-instantiation-templates', + view: '' + }); + var scopeVM = new DefineMap({ message: 'world' }); + var componentInstance = new ComponentConstructor({ + scope: scopeVM, + templates: { messageInput: '' } + }); + var element = componentInstance.element; + var inputElement = element.querySelector('input'); + QUnit.ok(inputElement, 'template rendered'); + QUnit.equal(inputElement.value, 'world', 'input has correct value'); + scopeVM.message = 'mundo'; + QUnit.equal(inputElement.value, 'mundo', 'input has correct value after updating scopeVM'); + }); + QUnit.test('Components can be instantiated with viewModel', function () { + var bindMap = new SimpleMap({ inner: new SimpleMap({ key: 'original bind value' }) }); + var fromMap = new SimpleMap({ inner: new SimpleMap({ key: 'original from value' }) }); + var toMap = new SimpleMap({ inner: new SimpleMap({ key: 'original to value' }) }); + var ComponentConstructor = Component.extend({ + tag: 'new-instantiation-viewmodel', + view: 'Hello', + ViewModel: { + fromChildProp: 'string', + plainProp: 'string', + toParentProp: 'string', + twoWayProp: 'string', + nullProp: { + default: function () { + return 'bar'; + } + } + } + }); + var componentInstance = new ComponentConstructor({ + viewModel: { + plainProp: 'plain value', + fromChildProp: value.from(fromMap, 'inner.key'), + toParentProp: value.to(toMap, 'inner.key'), + twoWayProp: value.bind(bindMap, 'inner.key'), + nullProp: null + } + }); + var viewModel = componentInstance.viewModel; + QUnit.equal(viewModel.fromChildProp, 'original from value', 'fromChildProp init'); + QUnit.equal(viewModel.plainProp, 'plain value', 'plainProp init'); + QUnit.equal(viewModel.toParentProp, undefined, 'toParentProp init'); + QUnit.equal(viewModel.twoWayProp, 'original bind value', 'twoWayProp init'); + QUnit.equal(viewModel.nullProp, null, 'nullProp init'); + fromMap.get('inner').set('key', 'new from value'); + QUnit.equal(viewModel.fromChildProp, 'new from value', 'viewModel updated after fromMap set'); + viewModel.toParentProp = 'new to value'; + QUnit.equal(toMap.get('inner').get('key'), 'new to value', 'toMap updated after viewModel set'); + bindMap.get('inner').set('key', 'new bind value'); + QUnit.equal(viewModel.twoWayProp, 'new bind value', 'viewModel updated after bindMap set'); + viewModel.twoWayProp = 'newest bind value'; + QUnit.equal(bindMap.get('inner').get('key'), 'newest bind value', 'bindMap updated after viewModel set'); + }); + QUnit.test('Components can be instantiated with all options', function () { + var HelloWorld = Component.extend({ + tag: 'hello-world', + view: 'Hello world
      {{#each(items)}} {{/each}}
    ', + ViewModel: { items: {} } + }); + var componentInstance = new HelloWorld({ + content: '{{message}}', + scope: { message: 'friend' }, + templates: { itemTemplate: '
  1. {{this}}
  2. ' }, + viewModel: { items: ['eat'] } + }); + var element = componentInstance.element; + var viewModel = componentInstance.viewModel; + QUnit.equal(element.innerHTML, 'Hello friend
    • eat
    ', 'element renders correctly'); + QUnit.equal(viewModel.items.length, 1, 'viewModel has items'); + viewModel.items.push('sleep'); + QUnit.equal(element.innerHTML, 'Hello friend
    • eat
    • sleep
    ', 'element updates correctly'); + }); + QUnit.test('Component binding instantiation works as documented', function () { + var appVM = new SimpleMap({ + family: new SimpleMap({ + first: 'Milo', + last: 'Flanders' + }) + }); + var NameComponent = Component.extend({ + tag: 'name-component', + view: '{{fullName}}', + ViewModel: { + givenName: 'string', + familyName: 'string', + get fullName() { + return this.givenName + ' ' + this.familyName; + } + } + }); + var componentInstance = new NameComponent({ + viewModel: { + givenName: value.from(appVM, 'family.first'), + familyName: value.bind(appVM, 'family.last'), + fullName: value.to(appVM, 'family.full') + } + }); + var viewModel = componentInstance.viewModel; + QUnit.equal(viewModel.familyName, 'Flanders', 'component \u201Cbind\u201D prop is correct'); + QUnit.equal(viewModel.givenName, 'Milo', 'component \u201Cfrom\u201D prop is correct'); + QUnit.equal(viewModel.fullName, 'Milo Flanders', 'component \u201Cto\u201D prop is correct'); + var family = appVM.get('family'); + QUnit.equal(family.get('last'), 'Flanders', 'map \u201Cbind\u201D prop is correct'); + QUnit.equal(family.get('first'), 'Milo', 'map \u201Cfrom\u201D prop is correct'); + QUnit.equal(family.get('full'), 'Milo Flanders', 'map \u201Cto\u201D prop is correct'); + }); + QUnit.test('component instantiation is not observable', function () { + var innerViewModel; + var InnerComponent = Component.extend({ + tag: 'inner-component-to-make', + view: '{{this.innerValue}}', + ViewModel: { + init: function () { + innerViewModel = this; + }, + innerValue: 'any' + } + }); + var count = 0; + Component.extend({ + tag: 'outer-component-creator', + view: '{{{ this.innerComponent }}}', + ViewModel: { + get innerComponent() { + count++; + return new InnerComponent({ viewModel: { innerValue: value.bind(this, 'outerValue') } }); + }, + outerValue: 'any' + } + }); + var view = stache(''); + view(); + innerViewModel.innerValue = 'SOME-VALUE'; + QUnit.equal(count, 1, 'only updated once'); + }); +}); +/*can-component@4.4.9#test/component-in-stache-test*/ +define('can-component@4.4.9#test/component-in-stache-test', [ + 'require', + 'exports', + 'module', + 'can-component', + 'can-simple-map', + 'can-simple-observable', + 'can-stache', + 'can-reflect', + 'steal-qunit', + 'can-dom-mutate', + 'can-globals' +], function (require, exports, module) { + (function (global, require, exports, module) { + var Component = require('can-component'); + var SimpleMap = require('can-simple-map'); + var SimpleObservable = require('can-simple-observable'); + var stache = require('can-stache'); + var canReflect = require('can-reflect'); + var QUnit = require('steal-qunit'); + var domMutate = require('can-dom-mutate'); + var globals = require('can-globals'); + QUnit.module('can-component can be rendered by can-stache'); + QUnit.test('basics work', function (assert) { + var ComponentConstructor = Component.extend({ + tag: 'component-in-stache', + view: 'Hello {{message}}', + ViewModel: { message: 'string' } + }); + var componentInstance = new ComponentConstructor(); + var fragment = stache('
    {{{componentInstance}}}
    ')({ componentInstance: componentInstance }); + var viewModel = componentInstance.viewModel; + assert.equal(fragment.textContent, 'Hello ', 'fragment has correct text content'); + viewModel.message = 'world'; + assert.equal(fragment.textContent, 'Hello world', 'fragment has correct text content after updating viewModel'); + }); + QUnit.test('wrapped in a conditional', function (assert) { + var done = assert.async(); + var ComponentConstructor = Component.extend({ + tag: 'component-in-stache', + view: 'Hello {{message}}', + ViewModel: { message: 'string' } + }); + var componentInstance = new ComponentConstructor(); + var templateVM = new SimpleMap({ + componentInstance: componentInstance, + showComponent: false + }); + var componentVM = componentInstance.viewModel; + var fragment = stache('
    {{#if(showComponent)}}{{{componentInstance}}}{{/if}}
    ')(templateVM); + assert.equal(fragment.textContent, '', 'fragment starts off without content'); + templateVM.set('showComponent', true); + assert.equal(fragment.textContent, 'Hello ', 'fragment updates to include the component'); + componentVM.message = 'world'; + assert.equal(fragment.textContent, 'Hello world', 'fragment has correct text content after updating componentVM'); + canReflect.onInstanceBoundChange(ComponentConstructor.ViewModel, function (instance, isBound) { + assert.equal(isBound, false, 'view model is no longer bound'); + done(); + }); + templateVM.set('showComponent', false); + assert.equal(fragment.textContent, '', 'fragment ends without content'); + }); + QUnit.test('Component can be removed from the page', 3, function () { + var ToBeRemoved = Component.extend({ + tag: 'to-be-removed', + view: '{{prop}}', + ViewModel: { prop: 'string' }, + events: { + '{element} beforeremove': function () { + QUnit.ok(true, 'torn down'); + } + } + }); + var prop = new SimpleObservable(3); + var toBeRemoved = new ToBeRemoved({ viewModel: { prop: prop } }); + var show = new SimpleObservable(true); + var template = stache('
    {{# if(show) }} {{{toBeRemoved}}} {{/ if}}
    '); + var frag = template({ + show: show, + toBeRemoved: toBeRemoved + }); + show.set(false); + QUnit.ok(true, 'got here without an error'); + show.set(true); + prop.set(4); + QUnit.equal(frag.firstChild.getElementsByTagName('to-be-removed')[0].innerHTML, '4'); + }); + QUnit.test('Cleans up itself on the documentElement removal', function () { + Component.extend({ + tag: 'ssr-cleanup', + view: 'hello world', + ViewModel: {} + }); + var doc = document.implementation.createHTMLDocument('Test'); + var realDoc = globals.getKeyValue('document'); + globals.setKeyValue('document', doc); + var frag = stache('')({}); + doc.body.appendChild(frag); + domMutate.onNodeRemoval(doc.body.firstChild, function () { + globals.setKeyValue('document', realDoc); + QUnit.ok(true, 'Called back without throwing'); + start(); + }); + stop(); + doc.removeChild(doc.documentElement); + }); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-component@4.4.9#test/component-can-bind-test*/ +define('can-component@4.4.9#test/component-can-bind-test', [ + 'require', + 'exports', + 'module', + 'can-bind', + 'can-component', + './helpers', + 'steal-qunit', + 'can-simple-map', + 'can-value' +], function (require, exports, module) { + var Bind = require('can-bind'); + var Component = require('can-component'); + var helpers = require('./helpers'); + var QUnit = require('steal-qunit'); + var SimpleMap = require('can-simple-map'); + var value = require('can-value'); + QUnit.module('can-component integration with can-bind'); + QUnit.test('Using can-bind in connectedCallback works as documented', function (assert) { + var done = assert.async(); + var connectedCallbackCallCount = 0; + var BindComponent = Component.extend({ + tag: 'bind-component', + view: '{{object.prop}}', + ViewModel: { + eventualProp: { default: undefined }, + object: { + default: function () { + return new SimpleMap({ prop: 15 }); + } + }, + connectedCallback: function () { + connectedCallbackCallCount += 1; + var binding = new Bind({ + parent: value.from(this, 'eventualProp'), + child: value.to(this, 'object.prop') + }); + binding.start(); + return binding.stop.bind(binding); + } + } + }); + var componentInstance = new BindComponent({}); + var element = componentInstance.element; + var viewModel = componentInstance.viewModel; + assert.equal(viewModel.object.get('prop'), 15, 'view model prop starts off with initial value'); + var fixture = document.getElementById('qunit-fixture'); + fixture.appendChild(element); + helpers.afterMutation(function () { + assert.equal(viewModel.object.get('prop'), undefined, 'binding updates view model prop'); + viewModel.eventualProp = 22; + assert.equal(viewModel.object.get('prop'), 22, 'new value for one prop updates the other'); + assert.equal(connectedCallbackCallCount, 1, 'connectedCallback only called once'); + fixture.removeChild(element); + done(); + }); + }); +}); +/*can-component@4.4.9#test/test*/ +define('can-component@4.4.9#test/test', [ + 'require', + 'exports', + 'module', + './component-tag-test', + './component-viewmodel-test', + './component-viewmodel-observe-test', + './component-view-test', + './component-helpers-test', + './component-events-test', + './example-test', + './component-slot-test', + './component-define-test', + './component-instantiation-test', + './component-in-stache-test', + './component-can-bind-test' +], function (require, exports, module) { + require('./component-tag-test'); + require('./component-viewmodel-test'); + require('./component-viewmodel-observe-test'); + require('./component-view-test'); + require('./component-helpers-test'); + require('./component-events-test'); + require('./example-test'); + require('./component-slot-test'); + require('./component-define-test'); + require('./component-instantiation-test'); + require('./component-in-stache-test'); + require('./component-can-bind-test'); +}); +/*can-define@2.7.1#test/test-define-only*/ +define('can-define@2.7.1#test/test-define-only', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-define', + 'can-queues', + 'can-symbol', + 'can-simple-observable', + 'can-test-helpers', + 'can-reflect', + 'can-observation-recorder' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var define = require('can-define'); + var queues = require('can-queues'); + var canSymbol = require('can-symbol'); + var SimpleObservable = require('can-simple-observable'); + var testHelpers = require('can-test-helpers'); + var canReflect = require('can-reflect'); + var ObservationRecorder = require('can-observation-recorder'); + QUnit.module('can-define'); + QUnit.test('basics on a prototype', 5, function () { + var Person = function (first, last) { + this.first = first; + this.last = last; + }; + define(Person.prototype, { + first: '*', + last: '*', + fullName: { + get: function () { + return this.first + ' ' + this.last; + } + } + }); + var p = new Person('Mohamed', 'Cherif'); + p.bind('fullName', function (ev, newVal, oldVal) { + QUnit.equal(oldVal, 'Mohamed Cherif'); + QUnit.equal(newVal, 'Justin Meyer'); + }); + equal(p.fullName, 'Mohamed Cherif', 'fullName initialized right'); + p.bind('first', function (el, newVal, oldVal) { + QUnit.equal(newVal, 'Justin', 'first new value'); + QUnit.equal(oldVal, 'Mohamed', 'first old value'); + }); + queues.batch.start(); + p.first = 'Justin'; + p.last = 'Meyer'; + queues.batch.stop(); + }); + QUnit.test('basics set', 2, function () { + var Defined = function (prop) { + this.prop = prop; + }; + define(Defined.prototype, { + prop: { + set: function (newVal) { + return 'foo' + newVal; + } + } + }); + var def = new Defined(); + def.prop = 'bar'; + QUnit.equal(def.prop, 'foobar', 'setter works'); + var DefinedCB = function (prop) { + this.prop = prop; + }; + define(DefinedCB.prototype, { + prop: { + set: function (newVal, setter) { + setter('foo' + newVal); + } + } + }); + var defCallback = new DefinedCB(); + defCallback.prop = 'bar'; + QUnit.equal(defCallback.prop, 'foobar', 'setter callback works'); + }); + QUnit.test('basic Type', function () { + var Foo = function (name) { + this.name = name; + }; + Foo.prototype.getName = function () { + return this.name; + }; + var Typer = function (foo) { + this.foo = foo; + }; + define(Typer.prototype, { foo: { Type: Foo } }); + var t = new Typer('Justin'); + QUnit.equal(t.foo.getName(), 'Justin', 'correctly created an instance'); + var brian = new Foo('brian'); + t.foo = brian; + QUnit.equal(t.foo, brian, 'same instances'); + }); + QUnit.test('type converters', function () { + var Typer = function (date, string, number, bool, htmlbool, leaveAlone) { + this.date = date; + this.string = string; + this.number = number; + this.bool = bool; + this.htmlbool = htmlbool; + this.leaveAlone = leaveAlone; + }; + define(Typer.prototype, { + date: { type: 'date' }, + string: { type: 'string' }, + number: { type: 'number' }, + bool: { type: 'boolean' }, + htmlbool: { type: 'htmlbool' }, + leaveAlone: { type: '*' } + }); + var obj = {}; + var t = new Typer(1395896701516, 5, '5', 'false', '', obj); + QUnit.ok(t.date instanceof Date, 'converted to date'); + QUnit.equal(t.string, '5', 'converted to string'); + QUnit.equal(t.number, 5, 'converted to number'); + QUnit.equal(t.bool, false, 'converted to boolean'); + QUnit.equal(t.htmlbool, true, 'converted to htmlbool'); + QUnit.equal(t.leaveAlone, obj, 'left as object'); + t.number = '15'; + QUnit.ok(t.number === 15, 'converted to number'); + }); + QUnit.test('basics value', function () { + var Typer = function (prop) { + if (prop !== undefined) { + this.prop = prop; + } + }; + define(Typer.prototype, { prop: { default: 'foo' } }); + var t = new Typer(); + QUnit.equal(t.prop, 'foo', 'value is used as default value'); + var Typer2 = function (prop) { + if (prop !== undefined) { + this.prop = prop; + } + }; + define(Typer2.prototype, { + prop: { + default: function () { + return []; + }, + type: '*' + } + }); + var t1 = new Typer2(), t2 = new Typer2(); + QUnit.ok(t1.prop !== t2.prop, 'different array instances'); + QUnit.ok(Array.isArray(t1.prop), 'its an array'); + }); + test('basics Value', function () { + var Typer = function (prop) { + }; + define(Typer.prototype, { + prop: { + Default: Array, + type: '*' + } + }); + var t1 = new Typer(), t2 = new Typer(); + QUnit.ok(t1.prop !== t2.prop, 'different array instances'); + QUnit.ok(Array.isArray(t1.prop), 'its an array'); + }); + test('setter with no arguments and returns undefined does the default behavior, the setter is for side effects only', function () { + var Typer = function (prop) { + }; + define(Typer.prototype, { + prop: { + set: function () { + this.foo = 'bar'; + } + }, + foo: '*' + }); + var t = new Typer(); + t.prop = false; + deepEqual({ + foo: t.foo, + prop: t.prop + }, { + foo: 'bar', + prop: false + }, 'got the right props'); + }); + test('type happens before the set', 2, function () { + var Typer = function () { + }; + define(Typer.prototype, { + prop: { + type: 'number', + set: function (newValue) { + equal(typeof newValue, 'number', 'got a number'); + return newValue + 1; + } + } + }); + var map = new Typer(); + map.prop = '5'; + equal(map.prop, 6, 'number'); + }); + test('getter and setter work', function () { + expect(5); + var Paginate = define.Constructor({ + limit: '*', + offset: '*', + page: { + set: function (newVal) { + this.offset = (parseInt(newVal) - 1) * this.limit; + }, + get: function () { + return Math.floor(this.offset / this.limit) + 1; + } + } + }); + var p = new Paginate({ + limit: 10, + offset: 20 + }); + equal(p.page, 3, 'page get right'); + p.bind('page', function (ev, newValue, oldValue) { + equal(newValue, 2, 'got new value event'); + equal(oldValue, 3, 'got old value event'); + }); + p.page = 2; + equal(p.page, 2, 'page set right'); + equal(p.offset, 10, 'page offset set'); + }); + test('getter with initial value', function () { + var comp = new SimpleObservable(1); + var Grabber = define.Constructor({ + vals: { + type: '*', + Default: Array, + get: function (current, setVal) { + if (setVal) { + current.push(comp.get()); + } + return current; + } + } + }); + var g = new Grabber(); + equal(g.vals.length, 0, 'zero items in array'); + }); + test('default behaviors with "*" work for attributes', function () { + expect(6); + var DefaultMap = define.Constructor({ + '*': { + type: 'number', + set: function (newVal) { + ok(true, 'set called'); + return newVal; + } + }, + someNumber: { default: '5' }, + number: {} + }); + var map = new DefaultMap(); + equal(map.someNumber, '5', 'default values are not type converted anymore'); + map.someNumber = '5'; + equal(map.someNumber, 5, 'on a set, they should be type converted'); + map.number = '10'; + equal(map.number, 10, 'value of number should be converted to a number'); + }); + test('nested define', function () { + var nailedIt = 'Nailed it'; + var Example = define.Constructor({ name: { default: nailedIt } }); + var NestedMap = define.Constructor({ + isEnabled: { default: true }, + test: { Default: Example }, + examples: { + type: { + one: { Default: Example }, + two: { + type: { deep: { Default: Example } }, + Default: Object + } + }, + Default: Object + } + }); + var nested = new NestedMap(); + equal(nested.test.name, nailedIt); + equal(nested.examples.one.name, nailedIt); + equal(nested.examples.two.deep.name, nailedIt); + ok(nested.test instanceof Example); + ok(nested.examples.one instanceof Example); + ok(nested.examples.two.deep instanceof Example); + }); + test('Can make an attr alias a compute (#1470)', 9, function () { + var computeValue = new SimpleObservable(1); + var GetMap = define.Constructor({ + value: { + set: function (newValue, setVal, oldValue) { + if (newValue instanceof SimpleObservable) { + return newValue; + } + if (oldValue && oldValue instanceof SimpleObservable) { + oldValue.set(newValue); + return oldValue; + } + return newValue; + }, + get: function (value) { + return value instanceof SimpleObservable ? value.get() : value; + } + } + }); + var getMap = new GetMap(); + getMap.value = computeValue; + equal(getMap.value, 1, 'initial value read from compute'); + var bindCallbacks = 0; + getMap.bind('value', function (ev, newVal, oldVal) { + switch (bindCallbacks) { + case 0: + equal(newVal, 2, '0 - bind called with new val'); + equal(oldVal, 1, '0 - bind called with old val'); + break; + case 1: + equal(newVal, 3, '1 - bind called with new val'); + equal(oldVal, 2, '1 - bind called with old val'); + break; + case 2: + equal(newVal, 4, '2 - bind called with new val'); + equal(oldVal, 3, '2 - bind called with old val'); + break; + } + bindCallbacks++; + }); + computeValue.set(2); + getMap.value = 3; + equal(getMap.value, 3, 'read value is 3'); + equal(computeValue.get(), 3, 'the compute value is 3'); + var newComputeValue = new SimpleObservable(4); + getMap.value = newComputeValue; + }); + test('One event on getters (#1585)', function () { + var Person = define.Constructor({ + name: '*', + id: 'number' + }); + var AppState = define.Constructor({ + person: { + get: function appState_person_get(lastSetValue, resolve) { + if (lastSetValue) { + return lastSetValue; + } else if (this.personId) { + resolve(new Person({ + name: 'Jose', + id: 5 + })); + } else { + return null; + } + }, + Type: Person + }, + personId: '*' + }); + var appState = new AppState(); + var personEvents = 0; + appState.bind('person', function addPersonEvents(ev, person) { + personEvents++; + }); + equal(appState.person, null, 'no personId and no lastSetValue'); + appState.personId = 5; + equal(appState.person.name, 'Jose', 'a personId, providing Jose'); + ok(appState.person instanceof Person, 'got a person instance'); + appState.person = { name: 'Julia' }; + ok(appState.person instanceof Person, 'got a person instance'); + equal(personEvents, 2); + }); + test('Can read a defined property with a set/get method (#1648)', function () { + var Map = define.Constructor({ + foo: { + default: '', + set: function (setVal) { + return setVal; + }, + get: function (lastSetVal) { + return lastSetVal; + } + } + }); + var map = new Map(); + equal(map.foo, '', 'Calling .foo returned the correct value'); + map.foo = 'baz'; + equal(map.foo, 'baz', 'Calling .foo returned the correct value'); + }); + test('Can bind to a defined property with a set/get method (#1648)', 3, function () { + var Map = define.Constructor({ + foo: { + default: '', + set: function (setVal) { + return setVal; + }, + get: function (lastSetVal) { + return lastSetVal; + } + } + }); + var map = new Map(); + map.bind('foo', function () { + ok(true, 'Bound function is called'); + }); + equal(map.foo, '', 'Calling .attr(\'foo\') returned the correct value'); + map.foo = 'baz'; + equal(map.foo, 'baz', 'Calling .attr(\'foo\') returned the correct value'); + }); + test('type converters handle null and undefined in expected ways (1693)', function () { + var Typer = define.Constructor({ + date: { type: 'date' }, + string: { type: 'string' }, + number: { type: 'number' }, + 'boolean': { type: 'boolean' }, + htmlbool: { type: 'htmlbool' }, + leaveAlone: { type: '*' } + }); + var t = new Typer({ + date: undefined, + string: undefined, + number: undefined, + 'boolean': undefined, + htmlbool: undefined, + leaveAlone: undefined + }); + equal(t.date, undefined, 'converted to date'); + equal(t.string, undefined, 'converted to string'); + equal(t.number, undefined, 'converted to number'); + equal(t.boolean, undefined, 'converted to boolean'); + equal(t.htmlbool, false, 'converted to htmlbool'); + equal(t.leaveAlone, undefined, 'left as object'); + t = new Typer({ + date: null, + string: null, + number: null, + 'boolean': null, + htmlbool: null, + leaveAlone: null + }); + equal(t.date, null, 'converted to date'); + equal(t.string, null, 'converted to string'); + equal(t.number, null, 'converted to number'); + equal(t.boolean, null, 'converted to boolean'); + equal(t.htmlbool, false, 'converted to htmlbool'); + equal(t.leaveAlone, null, 'left as object'); + }); + test('Initial value does not call getter', function () { + expect(0); + var Map = define.Constructor({ + count: { + get: function (lastVal) { + ok(false, 'Should not be called'); + return lastVal; + } + } + }); + new Map({ count: 100 }); + }); + test('getters produce change events', function () { + var Map = define.Constructor({ + count: { + get: function (lastVal) { + return lastVal; + } + } + }); + var map = new Map(); + map.bind('count', function () { + ok(true, 'change called'); + }); + map.count = 22; + }); + test('Asynchronous virtual properties cause extra recomputes (#1915)', function () { + stop(); + var ran = false; + var VM = define.Constructor({ + foo: { + get: function (lastVal, setVal) { + setTimeout(function () { + if (setVal) { + setVal(5); + } + }, 10); + } + }, + bar: { + get: function () { + var foo = this.foo; + if (foo) { + if (ran) { + ok(false, 'Getter ran twice'); + } + ran = true; + return foo * 2; + } + } + } + }); + var vm = new VM(); + vm.bind('bar', function () { + }); + setTimeout(function () { + equal(vm.bar, 10); + start(); + }, 200); + }); + QUnit.test('Default values cannot be set (#8)', function () { + var Person = function () { + }; + define(Person.prototype, { + first: { + type: 'string', + default: 'Chris' + }, + last: { + type: 'string', + default: 'Gomez' + }, + fullName: { + get: function () { + return this.first + ' ' + this.last; + } + } + }); + var p = new Person(); + QUnit.equal(p.fullName, 'Chris Gomez', 'Fullname is correct'); + p.first = 'Sara'; + QUnit.equal(p.fullName, 'Sara Gomez', 'Fullname is correct after update'); + }); + QUnit.test('default type is setable', function () { + var Person = function () { + }; + define(Person.prototype, { + '*': 'string', + first: { default: 1 }, + last: { default: 2 } + }); + var p = new Person(); + QUnit.ok(p.first === '1', typeof p.first); + QUnit.ok(p.last === '2', typeof p.last); + }); + QUnit.test('expandos are added in define.setup (#25)', function () { + var MyMap = define.Constructor({}); + var map = new MyMap({ prop: 4 }); + map.on('prop', function () { + QUnit.ok(true, 'prop event called'); + }); + map.prop = 5; + }); + QUnit.test('Set property with type compute', function () { + var MyMap = define.Constructor({ computeProp: { type: 'compute' } }); + var m = new MyMap(); + m.computeProp = new SimpleObservable(0); + equal(m.computeProp, 0, 'Property has correct value'); + m.computeProp = new SimpleObservable(1); + equal(m.computeProp, 1, 'Property has correct value'); + }); + QUnit.test('Compute type property can have a default value', function () { + var MyMap = define.Constructor({ + computeProp: { + type: 'compute', + default: function () { + return 0; + } + } + }); + var m = new MyMap(); + equal(m.computeProp, 0, 'Property has correct value'); + m.computeProp = 1; + equal(m.computeProp, 1, 'Property has correct value'); + }); + QUnit.test('Compute type property with compute default value triggers change events when updated', function () { + var expected = 0; + var c = new SimpleObservable(0); + var MyMap = define.Constructor({ + computeProp: { + type: 'compute', + default: function () { + return c; + } + } + }); + var m = new MyMap(); + c.on(function (newVal) { + equal(newVal, expected, 'Compute fired change event'); + }); + m.on('computeProp', function (ev, newVal) { + equal(newVal, expected, 'Map fired change event'); + }); + expected = 1; + m.computeProp = expected; + expected = 2; + c.set(expected); + }); + QUnit.test('Compute type property can have a default value that is a compute', function () { + var c = new SimpleObservable(0); + var MyMap = define.Constructor({ + computeProp: { + type: 'compute', + default: function () { + return c; + } + } + }); + var m = new MyMap(); + equal(m.computeProp, 0, 'Property has correct value'); + c.set(1); + equal(m.computeProp, 1, 'Property has correct value'); + }); + QUnit.test('Extensions can modify definitions', function () { + var oldExtensions = define.extensions; + define.behaviors.push('extended'); + define.extensions = function (objPrototype, prop, definition) { + if (definition.extended) { + return { default: 'extended' }; + } + }; + var MyMap = define.Constructor({ + foo: { + default: 'defined', + extended: true + }, + bar: { default: 'defined' } + }); + var map = new MyMap(); + QUnit.equal(map.foo, 'extended', 'Value was set via extension'); + QUnit.equal(map.bar, 'defined', 'Value was set via definition'); + define.extensions = oldExtensions; + }); + QUnit.test('Properties are enumerable', function () { + QUnit.expect(1); + function VM(foo) { + this.foo = foo; + } + define(VM.prototype, { foo: 'string' }); + var vm = new VM('bar'); + vm.baz = 'qux'; + var copy = {}; + for (var key in vm) { + copy[key] = vm[key]; + } + QUnit.deepEqual(copy, { + foo: 'bar', + baz: 'qux' + }); + }); + QUnit.test('Doesn\'t override canSymbol.iterator if already on the prototype', function () { + function MyMap() { + } + MyMap.prototype[canSymbol.iterator || canSymbol.for('iterator')] = function () { + var i = 0; + return { + next: function () { + if (i === 0) { + i++; + return { + value: [ + 'it', + 'worked' + ], + done: false + }; + } + return { + value: undefined, + done: true + }; + } + }; + }; + define(MyMap.prototype, { foo: 'string' }); + var map = new MyMap(); + map.foo = 'bar'; + canReflect.eachIndex(map, function (value) { + QUnit.deepEqual(value, [ + 'it', + 'worked' + ]); + }); + }); + QUnit.test('nullish values are not converted for type or Type', function (assert) { + var Foo = function () { + }; + var MyMap = define.Constructor({ + map: { Type: Foo }, + notype: {} + }); + var vm = new MyMap({ + map: {}, + notype: {} + }); + assert.ok(vm.map instanceof Foo, 'map is another type'); + assert.ok(vm.notype instanceof Object, 'notype is an Object'); + vm.map = null; + vm.notype = null; + assert.equal(vm.map, null, 'map is null'); + assert.equal(vm.map, null, 'notype is null'); + }); + QUnit.test('shorthand getter (#56)', function () { + var Person = function (first, last) { + this.first = first; + this.last = last; + }; + define(Person.prototype, { + first: '*', + last: '*', + get fullName() { + return this.first + ' ' + this.last; + } + }); + var p = new Person('Mohamed', 'Cherif'); + p.on('fullName', function (ev, newVal, oldVal) { + QUnit.equal(oldVal, 'Mohamed Cherif'); + QUnit.equal(newVal, 'Justin Meyer'); + }); + equal(p.fullName, 'Mohamed Cherif', 'fullName initialized right'); + queues.batch.start(); + p.first = 'Justin'; + p.last = 'Meyer'; + queues.batch.stop(); + }); + QUnit.test('shorthand getter setter (#56)', function () { + var Person = function (first, last) { + this.first = first; + this.last = last; + }; + define(Person.prototype, { + first: '*', + last: '*', + get fullName() { + return this.first + ' ' + this.last; + }, + set fullName(newVal) { + var parts = newVal.split(' '); + this.first = parts[0]; + this.last = parts[1]; + } + }); + var p = new Person('Mohamed', 'Cherif'); + p.on('fullName', function (ev, newVal, oldVal) { + QUnit.equal(oldVal, 'Mohamed Cherif'); + QUnit.equal(newVal, 'Justin Meyer'); + }); + equal(p.fullName, 'Mohamed Cherif', 'fullName initialized right'); + p.fullName = 'Justin Meyer'; + }); + QUnit.test('set and value work together (#87)', function () { + var Type = define.Constructor({ + prop: { + default: 2, + set: function (num) { + return num * num; + } + } + }); + var instance = new Type(); + QUnit.equal(instance.prop, 4, 'used setter'); + }); + QUnit.test('async setter is provided', 5, function () { + var RESOLVE; + var Type = define.Constructor({ + prop: { + default: 2, + set: function (num, resolve) { + resolve(num * num); + } + }, + prop2: { + default: 3, + set: function (num, resolve) { + RESOLVE = resolve; + } + } + }); + var instance = new Type(); + QUnit.equal(instance.prop, 4, 'used async setter'); + QUnit.equal(instance.prop2, undefined, 'used async setter'); + instance.on('prop2', function (ev, newVal, oldVal) { + QUnit.equal(newVal, 9, 'updated'); + QUnit.equal(oldVal, undefined, 'updated'); + }); + RESOLVE(9); + QUnit.equal(instance.prop2, 9, 'used async setter updates after'); + }); + QUnit.test('setter with default value causes an infinite loop (#142)', function () { + var A = define.Constructor({ + val: { + default: 'hello', + set: function (val) { + if (this.val) { + } + return val; + } + } + }); + var a = new A(); + QUnit.equal(a.val, 'hello', 'creating an instance should not cause an inifinte loop'); + }); + QUnit.test('defined properties are configurable', function () { + var A = define.Constructor({ + val: { + get: function () { + return 'foo'; + } + } + }); + var dataInitializers = A.prototype._define.dataInitializers, computedInitializers = A.prototype._define.computedInitializers; + var newDefinition = { + get: function () { + return 'bar'; + } + }; + define.property(A.prototype, 'val', newDefinition, dataInitializers, computedInitializers); + var a = new A(); + QUnit.equal(a.val, 'bar', 'It was redefined'); + }); + testHelpers.dev.devOnlyTest('Setting a value with only a get() generates a warning (#202)', function () { + QUnit.expect(7); + var VM = function () { + }; + var message = 'can-define: Set value for property ' + canReflect.getName(VM.prototype) + '.derivedProp ignored, as its definition has a zero-argument getter and no setter'; + var finishErrorCheck = testHelpers.dev.willWarn(message, function (actualMessage, success) { + QUnit.equal(actualMessage, message, 'Warning is expected message'); + QUnit.ok(success); + }); + define(VM.prototype, { + derivedProp: { + get: function () { + return 'Hello World'; + } + } + }); + var vm = new VM(); + vm.on('derivedProp', function () { + }); + vm.derivedProp = 'prop is set'; + QUnit.equal(vm.derivedProp, 'Hello World', 'Getter value is preserved'); + VM.shortName = 'VM'; + QUnit.equal(finishErrorCheck(), 1); + message = 'can-define: Set value for property ' + canReflect.getName(VM.prototype) + '.derivedProp ignored, as its definition has a zero-argument getter and no setter'; + finishErrorCheck = testHelpers.dev.willWarn(message, function (actualMessage, success) { + QUnit.equal(actualMessage, message, 'Warning is expected message'); + QUnit.ok(success); + }); + vm.derivedProp = 'prop is set'; + QUnit.equal(finishErrorCheck(), 1); + }); + testHelpers.dev.devOnlyTest('warn on using a Constructor for small-t type definitions', function () { + QUnit.expect(1); + var message = /can-define: the definition for [\w{}\.]+ uses a constructor for "type"\. Did you mean "Type"\?/; + var finishErrorCheck = testHelpers.dev.willWarn(message); + function Currency() { + return this; + } + Currency.prototype = { symbol: 'USD' }; + function VM() { + } + define(VM.prototype, { + currency: { + type: Currency, + default: function () { + return new Currency({}); + } + } + }); + QUnit.equal(finishErrorCheck(), 1); + }); + testHelpers.dev.devOnlyTest('warn with constructor for Value instead of Default (#340)', function () { + QUnit.expect(1); + var message = /can-define: Change the 'Value' definition for [\w\.{}]+.currency to 'Default'./; + var finishErrorCheck = testHelpers.dev.willWarn(message); + function Currency() { + return this; + } + Currency.prototype = { symbol: 'USD' }; + function VM() { + } + define(VM.prototype, { currency: { Value: Currency } }); + QUnit.equal(finishErrorCheck(), 1); + }); + QUnit.test('canReflect.onKeyValue (#363)', function () { + var Greeting = function (message) { + this.message = message; + }; + define(Greeting.prototype, { message: { type: 'string' } }); + var greeting = new Greeting('Hello'); + canReflect.onKeyValue(greeting, 'message', function (newVal, oldVal) { + QUnit.equal(newVal, 'bye'); + QUnit.equal(oldVal, 'Hello'); + }); + greeting.message = 'bye'; + }); + QUnit.test('value lastSet has default value (#397)', function () { + var Defaulted = function () { + }; + define(Defaulted.prototype, { + hasDefault: { + default: 42, + value: function hasDefaultValue(props) { + QUnit.equal(props.lastSet.get(), 42, 'props.lastSet works'); + props.resolve(props.lastSet.get()); + } + } + }); + var defaulted = new Defaulted(); + QUnit.equal(defaulted.hasDefault, 42, 'hasDefault value.lastSet set default value'); + }); + QUnit.test('binding computed properties do not observation recordings (#406)', function () { + var Type = function () { + }; + define(Type.prototype, { + prop: { + get: function () { + return 'foo'; + } + } + }); + var inst = new Type(); + ObservationRecorder.start(); + inst.on('prop', function () { + }); + var records = ObservationRecorder.stop(); + QUnit.equal(records.valueDependencies.size, 0, 'nothing recorded'); + }); +}); +/*can-define@2.7.1#list/list-test*/ +define('can-define@2.7.1#list/list-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-define/list/list', + 'can-define/map/map', + 'can-observation', + 'can-define', + 'can-reflect', + 'can-symbol', + 'can-log/dev/dev', + 'can-test-helpers/lib/dev', + 'can-assign' +], function (require, exports, module) { + 'use strict'; + var QUnit = require('steal-qunit'); + var DefineList = require('can-define/list/list'); + var DefineMap = require('can-define/map/map'); + var Observation = require('can-observation'); + var define = require('can-define'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var dev = require('can-log/dev/dev'); + var canTestHelpers = require('can-test-helpers/lib/dev'); + var assign = require('can-assign'); + QUnit.module('can-define/list/list'); + QUnit.test('List is an event emitter', function (assert) { + var Base = DefineList.extend({}); + assert.ok(Base.on, 'Base has event methods.'); + var List = Base.extend({}); + assert.ok(List.on, 'List has event methods.'); + }); + QUnit.test('creating an instance', function () { + var list = new DefineList([ + 'a', + 'b', + 'c' + ]); + list.on('add', function (ev, newVals, index) { + QUnit.deepEqual(newVals, ['d']); + QUnit.equal(index, 3); + }); + list.push('d'); + }); + test('list attr changes length', function () { + var l = new DefineList([ + 0, + 1, + 2 + ]); + l.set(3, 3); + equal(l.length, 4); + }); + test('remove on pop', function () { + var l = new DefineList([ + 0, + 1, + 2 + ]); + l.pop(); + equal(l.length, 2); + deepEqual(l.get(), [ + 0, + 1 + ]); + }); + test('list splice', function () { + var l = new DefineList([ + 0, + 1, + 2, + 3 + ]); + l.on('add', function (ev, newVals, index) { + deepEqual(newVals, [ + 'a', + 'b' + ], 'got the right newVals'); + equal(index, 1, 'adding items'); + }); + l.on('remove', function (ev, oldVals, index) { + deepEqual(oldVals, [ + 1, + 2 + ], 'got the right oldVals'); + equal(index, 1, 'no new Vals'); + }); + l.splice(1, 2, 'a', 'b'); + deepEqual(l.get(), [ + 0, + 'a', + 'b', + 3 + ], 'serialized'); + }); + test('Array accessor methods', 11, function () { + var l = new DefineList([ + 'a', + 'b', + 'c' + ]), sliced = l.slice(2), joined = l.join(' | '), concatenated = l.concat([ + 2, + 1 + ], new DefineList([0])); + ok(sliced instanceof DefineList, 'Slice is an Observable list'); + equal(sliced.length, 1, 'Sliced off two elements'); + equal(sliced[0], 'c', 'Single element as expected'); + equal(joined, 'a | b | c', 'Joined list properly'); + ok(concatenated instanceof DefineList, 'Concatenated is an Observable list'); + deepEqual(concatenated.serialize(), [ + 'a', + 'b', + 'c', + 2, + 1, + 0 + ], 'DefineList concatenated properly'); + l.forEach(function (letter, index) { + ok(true, 'Iteration'); + if (index === 0) { + equal(letter, 'a', 'First letter right'); + } + if (index === 2) { + equal(letter, 'c', 'Last letter right'); + } + }); + }); + test('Concatenated list items Equal original', function () { + var l = new DefineList([ + { firstProp: 'Some data' }, + { secondProp: 'Next data' } + ]), concatenated = l.concat([ + { hello: 'World' }, + { foo: 'Bar' } + ]); + ok(l[0] === concatenated[0], 'They are Equal'); + ok(l[1] === concatenated[1], 'They are Equal'); + }); + test('Lists with maps concatenate properly', function () { + var Person = DefineMap.extend(); + var People = DefineList.extend({ '#': Person }); + var Genius = Person.extend(); + var Animal = DefineMap.extend(); + var me = new Person({ name: 'John' }); + var animal = new Animal({ name: 'Tak' }); + var genius = new Genius({ name: 'Einstein' }); + var hero = { name: 'Ghandi' }; + var people = new People([]); + var specialPeople = new People([ + genius, + hero + ]); + people = people.concat([ + me, + animal, + specialPeople + ], specialPeople, [ + 1, + 2 + ], 3); + ok(people.length === 8, 'List length is right'); + ok(people[0] === me, 'Map in list === vars created before concat'); + ok(people[1] instanceof Person, 'Animal got serialized to Person'); + }); + test('splice removes items in IE (#562)', function () { + var l = new DefineList(['a']); + l.splice(0, 1); + ok(!l.get(0), 'all props are removed'); + }); + test('reverse triggers add/remove events (#851)', function () { + expect(4); + var l = new DefineList([ + 1, + 2, + 3 + ]); + l.on('add', function () { + ok(true, 'add called'); + }); + l.on('remove', function () { + ok(true, 'remove called'); + }); + l.on('length', function () { + ok(true, 'length should be called'); + }); + l.reverse(); + deepEqual(l.get(), [ + 3, + 2, + 1 + ], 'reversed'); + }); + QUnit.test('filter', function (assert) { + var l = new DefineList([ + { + id: 1, + name: 'John' + }, + { + id: 2, + name: 'Mary' + } + ]); + var filtered = l.filter(function (item) { + return item.name === 'Mary'; + }); + assert.notDeepEqual(filtered, l, 'not same object'); + assert.equal(filtered.length, 1, 'one item'); + assert.equal(filtered[0].name, 'Mary', 'filter works'); + }); + test('No Add Events if DefineList Splice adds the same items that it is removing. (#1277, #1399)', function () { + var list = new DefineList([ + 'a', + 'b' + ]); + list.bind('add', function () { + ok(false, 'Add callback should not be called.'); + }); + list.bind('remove', function () { + ok(false, 'Remove callback should not be called.'); + }); + var result = list.splice(0, 2, 'a', 'b'); + deepEqual(result, [ + 'a', + 'b' + ]); + }); + test('add event always returns an array as the value (#998)', function () { + var list = new DefineList([]), msg; + list.bind('add', function (ev, newElements, index) { + deepEqual(newElements, [4], msg); + }); + msg = 'works on push'; + list.push(4); + list.pop(); + msg = 'works on attr()'; + list.set(0, 4); + list.pop(); + msg = 'works on replace()'; + list.replace([4]); + }); + test('Setting with .set() out of bounds of length triggers add event with leading undefineds', function () { + var list = new DefineList([1]); + list.bind('add', function (ev, newElements, index) { + deepEqual(newElements, [ + undefined, + undefined, + 4 + ], 'Leading undefineds are included'); + equal(index, 1, 'Index takes into account the leading undefineds from a .set()'); + }); + list.set(3, 4); + }); + test('No events should fire if removals happened on empty arrays', function () { + var list = new DefineList([]), msg; + list.bind('remove', function (ev, removed, index) { + ok(false, msg); + }); + msg = 'works on pop'; + list.pop(); + msg = 'works on shift'; + list.shift(); + ok(true, 'No events were fired.'); + }); + test('setting an index out of bounds does not create an array', function () { + expect(1); + var l = new DefineList(); + l.set('1', 'foo'); + equal(l.get('1'), 'foo'); + }); + test('splice with similar but less items works (#1606)', function () { + var list = new DefineList([ + 'aa', + 'bb', + 'cc' + ]); + list.splice(0, list.length, 'aa', 'cc', 'dd'); + deepEqual(list.get(), [ + 'aa', + 'cc', + 'dd' + ]); + list.splice(0, list.length, 'aa', 'cc'); + deepEqual(list.get(), [ + 'aa', + 'cc' + ]); + }); + test('filter returns same list type (#1744)', function () { + var ParentList = DefineList.extend(); + var ChildList = ParentList.extend(); + var children = new ChildList([ + 1, + 2, + 3 + ]); + ok(children.filter(function () { + }) instanceof ChildList); + }); + test('reverse returns the same list instance (#1744)', function () { + var ParentList = DefineList.extend(); + var ChildList = ParentList.extend(); + var children = new ChildList([ + 1, + 2, + 3 + ]); + ok(children.reverse() === children); + }); + test('slice and join are observable by a compute (#1884)', function () { + expect(2); + var list = new DefineList([ + 1, + 2, + 3 + ]); + var sliced = new Observation(function () { + return list.slice(0, 1); + }); + canReflect.onValue(sliced, function (newVal) { + deepEqual(newVal.get(), [2], 'got a new DefineList'); + }); + var joined = new Observation(function () { + return list.join(','); + }); + canReflect.onValue(joined, function (newVal) { + equal(newVal, '2,3', 'joined is observable'); + }); + list.shift(); + }); + test('list.replace', function () { + var firstArray = [ + { + id: 1, + name: 'Marshall' + }, + { + id: 2, + name: 'Austin' + }, + { + id: 3, + name: 'Hyrum' + } + ]; + var myList = new DefineList(firstArray); + var newArray = [ + { + id: 4, + name: 'Aubree' + }, + { + id: 5, + name: 'Leah' + }, + { + id: 6, + name: 'Lily' + } + ]; + myList.replace(newArray); + equal(myList.length, 3); + equal(myList[0].name, 'Aubree'); + equal(myList[1].name, 'Leah'); + equal(myList[2].name, 'Lily', 'Can replace a List with an Array.'); + myList.replace(firstArray); + equal(myList.length, 3); + equal(myList[0].name, 'Marshall'); + equal(myList[1].name, 'Austin'); + equal(myList[2].name, 'Hyrum', 'Can replace a List with another List.'); + }); + test('list.map', function () { + var myArray = [ + { + id: 1, + name: 'Marshall' + }, + { + id: 2, + name: 'Austin' + }, + { + id: 3, + name: 'Hyrum' + } + ]; + var myList = new DefineList(myArray); + var newList = myList.map(function (person) { + person.lastName = 'Thompson'; + return person; + }); + equal(newList.length, 3); + equal(newList[0].name, 'Marshall'); + equal(newList[0].lastName, 'Thompson'); + equal(newList[1].name, 'Austin'); + equal(newList[1].lastName, 'Thompson'); + equal(newList[2].name, 'Hyrum'); + equal(newList[2].lastName, 'Thompson'); + var ExtendedList = DefineList.extend({ + testMe: function () { + return 'It Worked!'; + } + }); + var myExtendedList = new ExtendedList(myArray); + var newExtendedList = myExtendedList.map(function (person) { + person.lastName = 'Thompson'; + return person; + }); + try { + newExtendedList.testMe(); + } catch (err) { + QUnit.ok(err.message.match(/testMe/), 'Does not return the same type of list.'); + } + }); + test('list.sort a simple list', function () { + var myList = new DefineList([ + 'Marshall', + 'Austin', + 'Hyrum' + ]); + myList.sort(); + equal(myList.length, 3); + equal(myList[0], 'Austin'); + equal(myList[1], 'Hyrum'); + equal(myList[2], 'Marshall', 'Basic list was properly sorted.'); + }); + test('list.sort a list of objects', function () { + var objList = new DefineList([ + { + id: 1, + name: 'Marshall' + }, + { + id: 2, + name: 'Austin' + }, + { + id: 3, + name: 'Hyrum' + } + ]); + objList.sort(function (a, b) { + if (a.name < b.name) { + return -1; + } else if (a.name > b.name) { + return 1; + } else { + return 0; + } + }); + equal(objList.length, 3); + equal(objList[0].name, 'Austin'); + equal(objList[1].name, 'Hyrum'); + equal(objList[2].name, 'Marshall', 'List of objects was properly sorted.'); + }); + test('list.sort a list of objects without losing reference (#137)', function () { + var unSorted = new DefineList([ + { id: 3 }, + { id: 2 }, + { id: 1 } + ]); + var sorted = unSorted.slice(0).sort(function (a, b) { + return a.id > b.id ? 1 : a.id < b.id ? -1 : 0; + }); + equal(unSorted[0], sorted[2], 'items should be equal'); + }); + test('list defines', 6, function () { + var Todo = function (props) { + assign(this, props); + }; + define(Todo.prototype, { + completed: 'boolean', + destroyed: { default: false } + }); + Todo.prototype.destroy = function () { + this.destroyed = true; + }; + var TodoList = DefineList.extend({ + '*': Todo, + remaining: { + get: function () { + return this.filter({ completed: false }); + } + }, + completed: { + get: function () { + return this.filter({ completed: true }); + } + }, + destroyCompleted: function () { + this.completed.forEach(function (todo) { + todo.destroy(); + }); + }, + setCompletedTo: function (value) { + this.forEach(function (todo) { + todo.completed = value; + }); + } + }); + var todos = new TodoList([ + { completed: true }, + { completed: false } + ]); + ok(todos.item(0) instanceof Todo, 'correct instance'); + equal(todos.completed.length, 1, 'only one todo'); + todos.on('completed', function (ev, newVal, oldVal) { + ok(newVal instanceof TodoList, 'right type'); + equal(newVal.length, 2, 'all items'); + ok(oldVal instanceof TodoList, 'right type'); + equal(oldVal.length, 1, 'all items'); + }); + todos.setCompletedTo(true); + }); + QUnit.test('extending the base supports overwriting _eventSetup', function () { + var L = DefineList.extend({}); + Object.getOwnPropertyDescriptor(DefineMap.prototype, '_eventSetup'); + L.prototype.arbitraryProp = true; + ok(true, 'set arbitraryProp'); + L.prototype._eventSetup = function () { + }; + ok(true, 'worked'); + }); + QUnit.test('setting expandos on a DefineList', function () { + var DL = DefineList.extend({ count: 'number' }); + var dl = new DL(); + dl.assign({ + count: 5, + skip: 2 + }); + QUnit.equal(dl.get('count'), 5, 'read with .get defined'); + QUnit.equal(dl.count, 5, 'read with . defined'); + QUnit.equal(dl.get('skip'), 2, 'read with .get expando'); + QUnit.equal(dl.skip, 2, 'read with . expando'); + QUnit.equal(dl.get('limit'), undefined, 'read with .get undefined'); + }); + QUnit.test('passing a DefineList to DefineList (#33)', function () { + var m = new DefineList([ + {}, + {} + ]); + var m2 = new DefineList(m); + QUnit.deepEqual(m.get(), m2.get()); + QUnit.ok(m[0] === m2[0], 'index the same'); + QUnit.ok(m[1] === m2[1], 'index the same'); + }); + QUnit.test('reading and setting expandos', function () { + var list = new DefineList(); + var countObservation = new Observation(function () { + return list.get('count'); + }, null, function (newValue) { + QUnit.equal(newValue, 1000, 'got new value'); + }); + countObservation.start(); + list.set('count', 1000); + QUnit.equal(countObservation.value, 1000); + var list2 = new DefineList(); + list2.on('count', function (ev, newVal) { + QUnit.equal(newVal, 5); + }); + list2.set('count', 5); + }); + QUnit.test('extending DefineList constructor functions (#61)', function () { + var AList = DefineList.extend('AList', { + aProp: {}, + aMethod: function () { + } + }); + var BList = AList.extend('BList', { + bProp: {}, + bMethod: function () { + } + }); + var CList = BList.extend('CList', { + cProp: {}, + cMethod: function () { + } + }); + var list = new CList([ + {}, + {} + ]); + list.on('aProp', function (ev, newVal, oldVal) { + QUnit.equal(newVal, 'PROP'); + QUnit.equal(oldVal, undefined); + }); + list.on('bProp', function (ev, newVal, oldVal) { + QUnit.equal(newVal, 'FOO'); + QUnit.equal(oldVal, undefined); + }); + list.on('cProp', function (ev, newVal, oldVal) { + QUnit.equal(newVal, 'BAR'); + QUnit.equal(oldVal, undefined); + }); + list.aProp = 'PROP'; + list.bProp = 'FOO'; + list.cProp = 'BAR'; + QUnit.ok(list.aMethod); + QUnit.ok(list.bMethod); + QUnit.ok(list.cMethod); + }); + QUnit.test('extending DefineList constructor functions more than once (#61)', function () { + var AList = DefineList.extend('AList', { + aProp: {}, + aMethod: function () { + } + }); + var BList = AList.extend('BList', { + bProp: {}, + bMethod: function () { + } + }); + var CList = AList.extend('CList', { + cProp: {}, + cMethod: function () { + } + }); + var list1 = new BList([ + {}, + {} + ]); + var list2 = new CList([ + {}, + {}, + {} + ]); + list1.on('aProp', function (ev, newVal, oldVal) { + QUnit.equal(newVal, 'PROP', 'aProp newVal on list1'); + QUnit.equal(oldVal, undefined); + }); + list1.on('bProp', function (ev, newVal, oldVal) { + QUnit.equal(newVal, 'FOO', 'bProp newVal on list1'); + QUnit.equal(oldVal, undefined); + }); + list2.on('aProp', function (ev, newVal, oldVal) { + QUnit.equal(newVal, 'PROP', 'aProp newVal on list2'); + QUnit.equal(oldVal, undefined); + }); + list2.on('cProp', function (ev, newVal, oldVal) { + QUnit.equal(newVal, 'BAR', 'cProp newVal on list2'); + QUnit.equal(oldVal, undefined); + }); + list1.aProp = 'PROP'; + list1.bProp = 'FOO'; + list2.aProp = 'PROP'; + list2.cProp = 'BAR'; + QUnit.ok(list1.aMethod, 'list1 aMethod'); + QUnit.ok(list1.bMethod); + QUnit.ok(list2.aMethod); + QUnit.ok(list2.cMethod, 'list2 cMethod'); + }); + QUnit.test('extending DefineList constructor functions - value (#61)', function () { + var AList = DefineList.extend('AList', { aProp: { default: 1 } }); + var BList = AList.extend('BList', {}); + var CList = BList.extend('CList', {}); + var c = new CList([]); + QUnit.equal(c.aProp, 1, 'got initial value'); + }); + QUnit.test('\'*\' inheritance works (#61)', function () { + var Account = DefineMap.extend({ + name: 'string', + amount: 'number', + slug: { + serialize: true, + get: function () { + return this.name.toLowerCase().replace(/ /g, '-').replace(/[^\w-]+/g, ''); + } + } + }); + var BaseList = DefineList.extend({ '*': Account }); + var ExtendedList = BaseList.extend({}); + var xl = new ExtendedList([{}]); + QUnit.ok(xl[0] instanceof Account); + }); + QUnit.test('shorthand getter setter (#56)', function () { + var People = DefineList.extend({ + first: '*', + last: '*', + get fullName() { + return this.first + ' ' + this.last; + }, + set fullName(newVal) { + var parts = newVal.split(' '); + this.first = parts[0]; + this.last = parts[1]; + } + }); + var p = new People([]); + p.fullName = 'Mohamed Cherif'; + p.on('fullName', function (ev, newVal, oldVal) { + QUnit.equal(oldVal, 'Mohamed Cherif'); + QUnit.equal(newVal, 'Justin Meyer'); + }); + equal(p.fullName, 'Mohamed Cherif', 'fullName initialized right'); + p.fullName = 'Justin Meyer'; + }); + QUnit.test('added and removed are called after items are added/removed (#14)', function () { + var Person = DefineMap.extend({ + id: 'number', + name: 'string' + }); + var addedFuncCalled, removedFuncCalled, theList; + var People = DefineList.extend({ + '#': { + added: function (items, index) { + addedFuncCalled = true; + ok(items, 'items added got passed to added'); + ok(typeof index === 'number', 'index of items was passed to added and is a number'); + ok(items[0].name === 'John', 'Name was correct'); + theList = this; + }, + removed: function (items, index) { + removedFuncCalled = true; + ok(items, 'items added got passed to removed'); + ok(typeof index === 'number', 'index of items was passed to removed and is a number'); + theList = this; + }, + Type: Person + }, + outsideProp: { + type: 'boolean', + default: true + } + }); + var people = new People([]); + var me = new Person(); + me.name = 'John'; + me.id = '1234'; + ok(!addedFuncCalled, 'added function has not been called yet'); + people.push(me); + ok(addedFuncCalled, 'added function was called'); + ok(theList.outsideProp === true && theList instanceof People, 'the list was passed correctly as this to added'); + theList = null; + ok(!removedFuncCalled, 'removed function has not been called yet'); + people.splice(people.indexOf(me), 1); + ok(removedFuncCalled, 'removed function was called'); + ok(theList.outsideProp === true && theList instanceof People, 'the list was passed correctly as this to removed'); + }); + QUnit.test('* vs # (#78)', function () { + var MyList = DefineList.extend({ + '*': 'number', + '#': { + added: function () { + ok(true, 'called on init'); + }, + removed: function () { + }, + type: 'string' + } + }); + var list = new MyList([ + 1, + 2, + 3 + ]); + QUnit.ok(list[0] === '1', 'converted to string'); + list.set('prop', '4'); + QUnit.ok(list.prop === 4, 'type converted'); + }); + QUnit.test('Array shorthand uses #', function () { + var MyMap = DefineMap.extend({ 'numbers': ['number'] }); + var map = new MyMap({ + numbers: [ + '1', + '2' + ] + }); + QUnit.ok(map.numbers[0] === 1, 'converted to number'); + map.numbers.set('prop', '4'); + QUnit.ok(map.numbers.prop === '4', 'type left alone'); + }); + QUnit.test('replace-with-self lists are diffed properly (can-view-live#10)', function () { + var a = new DefineMap({ name: 'A' }); + var b = new DefineMap({ name: 'B' }); + var c = new DefineMap({ name: 'C' }); + var d = new DefineMap({ name: 'D' }); + expect(4); + var list1 = new DefineList([ + a, + b + ]); + list1.on('add', function (ev, newVals, where) { + throw new Error('list1 should not add.'); + }); + list1.on('remove', function (ev, oldVals, where) { + throw new Error('list1 should not remove.'); + }); + list1.replace([ + a, + b + ]); + var list2 = new DefineList([ + a, + b, + c + ]); + list2.on('add', function (ev, newVals, where) { + equal(newVals.length, 1, 'list2 added length'); + equal(where, 2, 'list2 added location'); + }); + list2.on('remove', function (ev, oldVals, where) { + equal(oldVals.length, 1, 'list2 removed length'); + equal(where, 2, 'list2 removed location'); + }); + list2.replace([ + a, + b, + d + ]); + }); + QUnit.test('set >= length - triggers length event (#152)', function () { + var l = new DefineList([ + 1, + 2, + 3 + ]); + var batchNum = null; + l.on('add', function (e) { + ok(true, 'add called'); + if (batchNum === null) { + batchNum = e.batchNum; + } else { + equal(batchNum, e.batchNum, 'batch numbers match'); + } + }); + l.on('remove', function (e) { + ok(false, 'remove called'); + if (batchNum === null) { + batchNum = e.batchNum; + } else { + equal(batchNum, e.batchNum, 'batch numbers match'); + } + }); + l.on('length', function (e) { + ok(true, 'length called'); + if (batchNum === null) { + batchNum = e.batchNum; + } else { + equal(batchNum, e.batchNum, 'batch numbers match'); + } + }); + expect(4); + l.set(3, 5); + deepEqual(l.get(), [ + 1, + 2, + 3, + 5 + ], 'updated list'); + }); + QUnit.test('set < length - triggers length event (#150)', function () { + var l = new DefineList([ + 1, + 2, + 3 + ]); + var batchNum = null; + l.on('add', function (e) { + ok(true, 'add called'); + if (batchNum === null) { + batchNum = e.batchNum; + } else { + equal(batchNum, e.batchNum, 'batch numbers match'); + } + }); + l.on('remove', function (e) { + ok(true, 'remove called'); + if (batchNum === null) { + batchNum = e.batchNum; + } else { + equal(batchNum, e.batchNum, 'batch numbers match'); + } + }); + l.on('length', function (e) { + ok(true, 'length called'); + if (batchNum === null) { + batchNum = e.batchNum; + } else { + equal(batchNum, e.batchNum, 'batch numbers match'); + } + }); + expect(6); + l.set(2, 4); + deepEqual(l.get(), [ + 1, + 2, + 4 + ], 'updated list'); + }); + QUnit.test('set/splice are observable', function () { + var list = new DefineList([ + 1, + 2, + 3, + 4, + 5 + ]); + var count = new Observation(function () { + var count = 0; + for (var i = 0; i < list.length; i++) { + count += list[i] % 2 ? 1 : 0; + } + return count; + }); + canReflect.onValue(count, function () { + ok(true); + }); + expect(3); + list.set(3, 5); + list.set(2, 4); + list.splice(1, 1, 1); + }); + QUnit.test('setting length > current (#147)', function () { + var list = new DefineList([ + 1, + 2 + ]); + list.length = 5; + equal(list.length, 5); + equal(list.hasOwnProperty(0), true); + equal(list.hasOwnProperty(1), true); + equal(list.hasOwnProperty(2), true); + equal(list.hasOwnProperty(3), true); + equal(list.hasOwnProperty(4), true); + equal(list.hasOwnProperty(5), false); + }); + QUnit.test('setting length < current (#147)', function () { + var list = new DefineList([ + 1, + 2, + 3, + 4, + 5 + ]); + list.length = 3; + equal(list.length, 3); + equal(list.hasOwnProperty(0), true); + equal(list.hasOwnProperty(1), true); + equal(list.hasOwnProperty(2), true); + equal(list.hasOwnProperty(3), false); + equal(list.hasOwnProperty(4), false); + equal(list.hasOwnProperty(5), false); + }); + test('every', function () { + var l = new DefineList([ + { + id: 1, + name: 'Bob' + }, + { + id: 2, + name: 'Bob' + } + ]); + var allBobs = l.every(function (item) { + return item.name === 'Bob'; + }); + ok(allBobs, 'Every works in true case'); + var idOne = l.every(function (item) { + return item.id === 1; + }); + ok(!idOne, 'Every works in false case'); + allBobs = l.every({ name: 'Bob' }); + ok(allBobs, 'Every works in true case'); + idOne = l.every({ + name: 'Bob', + id: 1 + }); + ok(!idOne, 'Every works in false case'); + }); + test('some', function () { + var l = new DefineList([ + { + id: 1, + name: 'Alice' + }, + { + id: 2, + name: 'Bob' + } + ]); + var allBobs = l.some(function (item) { + return item.name === 'Bob'; + }); + ok(allBobs, 'Some works in true case'); + var idOne = l.some(function (item) { + return item.name === 'Charlie'; + }); + ok(!idOne, 'Some works in false case'); + allBobs = l.some({ name: 'Bob' }); + ok(allBobs, 'Some works in true case'); + idOne = l.some({ + name: 'Bob', + id: 1 + }); + ok(!idOne, 'Some works in false case'); + }); + test('lastIndexOf', function () { + var l = new DefineList([ + { + id: 1, + name: 'Alice' + }, + { + id: 2, + name: 'Bob' + } + ]); + var bobIdx = l.lastIndexOf(l[1]); + equal(bobIdx, 1, 'lastIndexOf found object'); + var charlieIdx = l.lastIndexOf({ + id: 3, + name: 'Charlie' + }); + equal(charlieIdx, -1, 'lastIndexOf not found object'); + l.push(l[1]); + bobIdx = l.lastIndexOf(l[1]); + equal(bobIdx, 2, 'lastIndexOf found last index of duped object'); + }); + test('reduce', function () { + var l = new DefineList([ + { + id: 1, + name: 'Alice', + score: 10 + }, + { + id: 2, + name: 'Bob', + score: 20 + } + ]); + var totalScores = l.reduce(function (total, player) { + return total + player.score; + }, 0); + equal(totalScores, 30, 'Reduce works over list'); + }); + test('reduceRight', function () { + var l = new DefineList([ + { + id: 1, + name: 'Alice' + }, + { + id: 2, + name: 'Bob' + } + ]); + var concatenatedNames = l.reduceRight(function (string, person) { + return string + person.name; + }, ''); + equal(concatenatedNames, 'BobAlice', 'ReduceRight works over list'); + }); + QUnit.test('can-reflect onKeyValue', function (assert) { + assert.expect(3); + var list = new DefineList([ + 1, + 2, + 3 + ]); + var key = 1; + canReflect.onKeyValue(list, key, function (newVal) { + assert.equal(newVal, 5); + }); + list.set(key, 5); + canReflect.onKeyValue(list, 'length', function (newVal) { + assert.equal(newVal, 4); + }); + list.push(6); + }); + test('works with can-reflect', function () { + var a = new DefineMap({ foo: 4 }); + var b = new DefineList([ + 'foo', + 'bar' + ]); + var c; + QUnit.equal(canReflect.getKeyValue(b, '0'), 'foo', 'unbound value'); + QUnit.ok(!canReflect.isValueLike(b), 'isValueLike is false'); + QUnit.ok(canReflect.isObservableLike(b), 'isObservableLike is true'); + QUnit.ok(canReflect.isMapLike(b), 'isMapLike is true'); + QUnit.ok(canReflect.isListLike(b), 'isListLike is false'); + QUnit.ok(!canReflect.keyHasDependencies(b, 'length'), 'keyHasDependencies -- false'); + define(c = Object.create(b), { + length: { + get: function () { + return a.foo; + } + } + }); + QUnit.ok(canReflect.getKeyDependencies(c, 'length'), 'dependencies exist'); + QUnit.ok(canReflect.getKeyDependencies(c, 'length').valueDependencies.has(c._computed.length.compute), 'dependencies returned'); + }); + QUnit.test('can-reflect setKeyValue', function () { + var a = new DefineList([ + 'a', + 'b' + ]); + canReflect.setKeyValue(a, 1, 'c'); + QUnit.equal(a[1], 'c', 'setKeyValue'); + }); + QUnit.test('can-reflect deleteKeyValue', function () { + var a = new DefineList([ + 'a', + 'b' + ]); + a.set('foo', 'bar'); + canReflect.deleteKeyValue(a, 0); + QUnit.equal(a[1], undefined, 'last value is now undefined'); + QUnit.equal(a[0], 'b', 'last value is shifted down'); + canReflect.deleteKeyValue(a, 'foo'); + QUnit.equal(a.foo, undefined, 'value not included in serial'); + QUnit.ok(!('foo' in a.get()), 'value not included in serial'); + }); + QUnit.test('can-reflect getKeyDependencies', function () { + var a = new DefineMap({ foo: 4 }); + var b = new DefineList([ + 'foo', + 'bar' + ]); + var c; + ok(!canReflect.getKeyDependencies(b, 'length'), 'No dependencies before binding'); + define(c = Object.create(b), { + length: { + get: function () { + return a.foo; + } + } + }); + ok(canReflect.getKeyDependencies(c, 'length'), 'dependencies exist'); + ok(canReflect.getKeyDependencies(c, 'length').valueDependencies.has(c._computed.length.compute), 'dependencies returned'); + }); + QUnit.test('assign property', function () { + var list = new DefineList([ + 'A', + 'B' + ]); + list.assign({ + count: 0, + skip: 2, + arr: [ + '1', + '2', + '3' + ] + }); + equal(list.get('count'), 0, 'Count set properly'); + list.assign({ + count: 1000, + arr: ['first'] + }); + deepEqual(list.get('arr'), new DefineList(['first']), 'Array is set properly'); + equal(list.get('count'), 1000, 'Count set properly'); + equal(list.get('skip'), 2, 'Skip is unchanged'); + }); + QUnit.test('update property', function () { + var list = new DefineList([ + 'A', + 'B' + ]); + list.update({ + count: 0, + skip: 2 + }); + equal(list.get('count'), 0, 'Count set properly'); + list.update({ count: 1000 }); + equal(list.get('count'), 1000, 'Count set properly'); + equal(list.get('skip'), undefined, 'Skip is changed'); + }); + QUnit.test('assignDeep property', function () { + var list = new DefineList([ + 'A', + 'B' + ]); + list.assignDeep({ + count: 0, + skip: 2, + foo: { + bar: 'zed', + tar: 'yap' + } + }); + equal(list.get('count'), 0, 'Count set properly'); + list.assignDeep({ + count: 1000, + foo: { bar: 'updated' } + }); + equal(list.get('count'), 1000, 'Count set properly'); + equal(list.get('skip'), 2, 'Skip is unchanged'); + propEqual(list.get('foo'), { + bar: 'updated', + tar: 'yap' + }, 'Foo was updated properly'); + }); + QUnit.test('updateDeep property', function () { + var list = new DefineList([ + 'A', + 'B' + ]); + list.updateDeep({ + count: 0, + skip: 2, + foo: { + bar: 'zed', + tar: 'yap' + } + }); + equal(list.get('count'), 0, 'Count set properly'); + list.updateDeep({ count: 1000 }); + equal(list.get('count'), 1000, 'Count set properly'); + equal(list.get('skip'), undefined, 'Skip is set to undefined'); + propEqual(list.get('foo'), undefined, 'Foo is set to undefined'); + }); + QUnit.test('registered symbols', function () { + var a = new DefineMap({ 'a': 'a' }); + ok(a[canSymbol.for('can.isMapLike')], 'can.isMapLike'); + equal(a[canSymbol.for('can.getKeyValue')]('a'), 'a', 'can.getKeyValue'); + a[canSymbol.for('can.setKeyValue')]('a', 'b'); + equal(a.a, 'b', 'can.setKeyValue'); + function handler(val) { + equal(val, 'c', 'can.onKeyValue'); + } + a[canSymbol.for('can.onKeyValue')]('a', handler); + a.a = 'c'; + a[canSymbol.for('can.offKeyValue')]('a', handler); + a.a = 'd'; + }); + QUnit.test('cannot remove length', function () { + var list = new DefineList(['a']); + list.set('length', undefined); + QUnit.equal(list.length, 1, 'list length is unchanged'); + }); + QUnit.test('cannot set length to a non-number', function () { + var list = new DefineList(['a']); + list.set('length', null); + QUnit.equal(list.length, 1, 'list length is unchanged'); + list.set('length', 'foo'); + QUnit.equal(list.length, 1, 'list length is unchanged'); + list.set('length', {}); + QUnit.equal(list.length, 1, 'list length is unchanged'); + }); + QUnit.test('_length is not enumerable', function () { + QUnit.ok(!Object.getOwnPropertyDescriptor(new DefineList(), '_length').enumerable, '_length is not enumerable'); + }); + QUnit.test('update with no indexed items sets length to 0', function () { + var list = new DefineList(['a']); + QUnit.equal(list.length, 1, 'list length is correct before update'); + list.update({ foo: 'bar' }); + QUnit.equal(list.length, 0, 'list length is correct after update'); + }); + [ + 'length', + '_length' + ].forEach(function (prop) { + QUnit.test('setting ' + prop + ' does not overwrite definition', function () { + var list = new DefineList(); + list.get(prop); + var proto = list, listDef, listDef2; + while (!listDef && proto) { + listDef = Object.getOwnPropertyDescriptor(proto, prop); + proto = Object.getPrototypeOf(proto); + } + list.set(prop, 1); + proto = list; + while (!listDef2 && proto) { + listDef2 = Object.getOwnPropertyDescriptor(proto, prop); + proto = Object.getPrototypeOf(proto); + } + delete listDef2.value; + delete listDef.value; + QUnit.deepEqual(listDef2, listDef, 'descriptor hasn\'t changed'); + }); + }); + QUnit.test('iterator can recover from bad _length', function () { + var list = new DefineList(['a']); + list.set('_length', null); + QUnit.equal(list._length, null, 'Bad value for _length'); + var iterator = list[canSymbol.iterator](); + var iteration = iterator.next(); + QUnit.ok(iteration.done, 'Didn\'t fail'); + }); + QUnit.test('onPatches', function () { + var list = new DefineList([ + 'a', + 'b' + ]); + var PATCHES = [ + [{ + deleteCount: 2, + index: 0, + type: 'splice' + }], + [{ + index: 0, + insert: [ + 'A', + 'B' + ], + deleteCount: 0, + type: 'splice' + }] + ]; + var calledPatches = []; + var handler = function patchesHandler(patches) { + calledPatches.push(patches); + }; + list[canSymbol.for('can.onPatches')](handler, 'notify'); + list.replace([ + 'A', + 'B' + ]); + list[canSymbol.for('can.offPatches')](handler, 'notify'); + list.replace([ + '1', + '2' + ]); + QUnit.deepEqual(calledPatches, PATCHES); + }); + canTestHelpers.devOnlyTest('can.getName symbol behavior', function (assert) { + var getName = function (instance) { + return instance[canSymbol.for('can.getName')](); + }; + assert.ok('DefineList[]', getName(new DefineList()), 'should use DefineList constructor name by default'); + var MyList = DefineList.extend('MyList', {}); + assert.ok('MyList[]', getName(new MyList()), 'should use custom list name when provided'); + }); + QUnit.test('length event should include previous value', function (assert) { + var done = assert.async(); + var list = new DefineList([]); + var other = new DefineList(['a']); + var changes = []; + list.on('length', function (_, current, previous) { + changes.push({ + current: current, + previous: previous + }); + }); + list.push('x'); + list.pop(); + list.push('y', 'z'); + list.splice(2, 0, 'x', 'w'); + list.splice(0, 1); + list.sort(); + list.replace(other); + assert.expect(1); + setTimeout(function () { + assert.deepEqual(changes, [ + { + current: 1, + previous: 0 + }, + { + current: 0, + previous: 1 + }, + { + current: 2, + previous: 0 + }, + { + current: 4, + previous: 2 + }, + { + current: 3, + previous: 4 + }, + { + current: 3, + previous: 3 + }, + { + current: 1, + previous: 3 + } + ], 'should include length before mutation'); + done(); + }); + }); + canTestHelpers.devOnlyTest('log all events', function (assert) { + var done = assert.async(); + var list = new DefineList([ + 'a', + 'b', + 'c' + ]); + list.set('total', 100); + list.log(); + var keys = []; + var log = dev.log; + dev.log = function () { + keys.push(JSON.parse(arguments[2])); + }; + list.push('x'); + list.pop(); + list.set('total', 50); + assert.expect(1); + setTimeout(function () { + dev.log = log; + assert.deepEqual(keys, [ + 'add', + 'length', + 'remove', + 'length', + 'total' + ], 'should log \'add\', \'remove\', \'length\' and \'propertyName\' events'); + done(); + }); + }); + canTestHelpers.devOnlyTest('log single events', function (assert) { + var done = assert.async(); + var list = new DefineList([ + 'a', + 'b', + 'c' + ]); + list.set('total', 100); + list.log('length'); + var keys = []; + var log = dev.log; + dev.log = function () { + keys.push(JSON.parse(arguments[2])); + }; + list.push('x'); + list.pop(); + list.set('total', 50); + assert.expect(1); + setTimeout(function () { + dev.log = log; + assert.deepEqual(keys, [ + 'length', + 'length' + ], 'should log \'length\' event'); + done(); + }); + }); + canTestHelpers.devOnlyTest('log multiple events', function (assert) { + var done = assert.async(); + var list = new DefineList([ + 'a', + 'b', + 'c' + ]); + list.set('total', 100); + list.log('add'); + list.log('total'); + var keys = []; + var log = dev.log; + dev.log = function () { + keys.push(JSON.parse(arguments[2])); + }; + list.push('x'); + list.pop(); + list.set('total', 50); + assert.expect(1); + setTimeout(function () { + dev.log = log; + assert.deepEqual(keys, [ + 'add', + 'total' + ], 'should log add and total'); + done(); + }); + }); + QUnit.test('DefineList has defineInstanceKey symbol', function () { + var Type = DefineList.extend({}); + Type[canSymbol.for('can.defineInstanceKey')]('prop', { type: 'number' }); + var t = new Type(); + t.prop = '5'; + QUnit.equal(t.prop, 5, 'value set'); + }); + QUnit.test('.sort() produces patches (can-stache#498)', function () { + var list = new DefineList([ + 'b', + 'a' + ]); + var PATCHES = [ + [{ + index: 0, + deleteCount: 2, + type: 'splice' + }], + [{ + index: 0, + insert: [ + 'a', + 'b' + ], + deleteCount: 0, + type: 'splice' + }] + ]; + var calledPatches = []; + var handler = function patchesHandler(patches) { + calledPatches.push(patches); + }; + list[canSymbol.for('can.onPatches')](handler, 'notify'); + list.sort(); + QUnit.deepEqual(calledPatches, PATCHES); + }); + QUnit.test('canReflect.getSchema', function () { + var MyType = DefineMap.extend({ + id: { + identity: true, + type: 'number' + }, + name: 'string' + }); + var MyList = DefineList.extend({ + count: 'number', + '#': MyType + }); + var schema = canReflect.getSchema(MyList); + QUnit.equal(schema.values, MyType); + }); + QUnit.test('Bound serialized lists update when they change length', function () { + QUnit.expect(1); + var list = new DefineList(['eggs']); + var obs = new Observation(function () { + return list.serialize(); + }); + function onChange(val) { + QUnit.deepEqual(val, [ + 'eggs', + 'toast' + ]); + } + canReflect.onValue(obs, onChange); + list.push('toast'); + canReflect.offValue(obs, onChange); + }); +}); +/*can-define@2.7.1#map/map-test*/ +define('can-define@2.7.1#map/map-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-define/map/map', + 'can-define', + 'can-observation', + 'can-assign', + 'can-reflect', + 'can-symbol', + 'can-test-helpers/lib/dev', + 'can-define/list/list', + 'can-log/dev/dev', + 'can-observation-recorder' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var DefineMap = require('can-define/map/map'); + var define = require('can-define'); + var Observation = require('can-observation'); + var assign = require('can-assign'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var isPlainObject = canReflect.isPlainObject; + var canTestHelpers = require('can-test-helpers/lib/dev'); + var DefineList = require('can-define/list/list'); + var dev = require('can-log/dev/dev'); + var ObservationRecorder = require('can-observation-recorder'); + var sealWorks = function () { + try { + var o = {}; + Object.seal(o); + o.prop = true; + return false; + } catch (e) { + return true; + } + }(); + QUnit.module('can-define/map/map'); + QUnit.test('Map is an event emitter', function (assert) { + var Base = DefineMap.extend({}); + assert.ok(Base.on, 'Base has event methods.'); + var Map = Base.extend({}); + assert.ok(Map.on, 'Map has event methods.'); + }); + QUnit.test('creating an instance', function () { + var map = new DefineMap({ prop: 'foo' }); + map.on('prop', function (ev, newVal, oldVal) { + QUnit.equal(newVal, 'BAR'); + QUnit.equal(oldVal, 'foo'); + }); + map.prop = 'BAR'; + }); + QUnit.test('creating an instance with nested prop', function () { + var map = new DefineMap({ name: { first: 'Justin' } }); + map.name.on('first', function (ev, newVal, oldVal) { + QUnit.equal(newVal, 'David'); + QUnit.equal(oldVal, 'Justin'); + }); + map.name.first = 'David'; + }); + QUnit.test('extending', function () { + var MyMap = DefineMap.extend({ prop: {} }); + var map = new MyMap(); + map.on('prop', function (ev, newVal, oldVal) { + QUnit.equal(newVal, 'BAR'); + QUnit.equal(oldVal, undefined); + }); + map.prop = 'BAR'; + }); + QUnit.test('loop only through defined serializable props', function () { + var MyMap = DefineMap.extend({ + propA: {}, + propB: { serialize: false }, + propC: { + get: function () { + return this.propA; + } + } + }); + var inst = new MyMap({ + propA: 1, + propB: 2 + }); + QUnit.deepEqual(Object.keys(inst.get()), ['propA']); + }); + QUnit.test('get and set can setup expandos', function () { + var map = new DefineMap(); + var oi = new Observation(function () { + return map.get('foo'); + }); + canReflect.onValue(oi, function (newVal) { + QUnit.equal(newVal, 'bar', 'updated to bar'); + }); + map.set('foo', 'bar'); + }); + QUnit.test('default settings', function () { + var MyMap = DefineMap.extend({ + '*': 'string', + foo: {} + }); + var m = new MyMap(); + m.set('foo', 123); + QUnit.ok(m.get('foo') === '123'); + }); + QUnit.test('default settings on unsealed', function () { + var MyMap = DefineMap.extend({ seal: false }, { '*': 'string' }); + var m = new MyMap(); + m.set('foo', 123); + QUnit.ok(m.get('foo') === '123'); + }); + if (!System.isEnv('production')) { + QUnit.test('extends sealed objects (#48)', function () { + var Map1 = DefineMap.extend({ seal: true }, { + name: { + get: function (curVal) { + return 'computed ' + curVal; + } + } + }); + var Map2 = Map1.extend({ seal: false }, {}); + var Map3 = Map2.extend({ seal: true }, {}); + var map1 = new Map1({ name: 'Justin' }); + try { + map1.foo = 'bar'; + if (map1.foo) { + QUnit.ok(false, 'map1 not sealed'); + } else { + QUnit.ok(true, 'map1 sealed - silent failure'); + } + } catch (ex) { + QUnit.ok(true, 'map1 sealed'); + } + QUnit.equal(map1.name, 'computed Justin', 'map1.name property is computed'); + var map2 = new Map2({ name: 'Brian' }); + try { + map2.foo = 'bar'; + if (map2.foo) { + QUnit.ok(true, 'map2 not sealed'); + } else { + QUnit.ok(false, 'map2 sealed'); + } + } catch (ex) { + QUnit.ok(false, 'map2 sealed'); + } + QUnit.equal(map2.name, 'computed Brian', 'map2.name property is computed'); + var map3 = new Map3({ name: 'Curtis' }); + try { + map3.foo = 'bar'; + if (map3.foo) { + QUnit.ok(false, 'map3 not sealed'); + } else { + QUnit.ok(true, 'map3 sealed'); + } + } catch (ex) { + QUnit.ok(true, 'map3 sealed'); + } + QUnit.equal(map3.name, 'computed Curtis', 'map3.name property is computed'); + }); + } + QUnit.test('get with dynamically added properties', function () { + var map = new DefineMap(); + map.set('a', 1); + map.set('b', 2); + QUnit.deepEqual(map.get(), { + a: 1, + b: 2 + }); + }); + QUnit.test('set multiple props', function () { + var map = new DefineMap(); + map.assign({ + a: 0, + b: 2 + }); + QUnit.deepEqual(map.get(), { + a: 0, + b: 2 + }, 'added props'); + map.update({ a: 2 }); + QUnit.deepEqual(map.get(), { a: 2 }, 'removed b'); + map.assign({ foo: { bar: 'VALUE' } }); + QUnit.deepEqual(map.get(), { + foo: { bar: 'VALUE' }, + a: 2 + }, 'works nested'); + }); + QUnit.test('serialize responds to added props', function () { + var map = new DefineMap(); + var oi = new Observation(function () { + return map.serialize(); + }); + canReflect.onValue(oi, function (newVal) { + QUnit.deepEqual(newVal, { + a: 1, + b: 2 + }, 'updated right'); + }); + map.assign({ + a: 1, + b: 2 + }); + }); + QUnit.test('initialize an undefined property', function () { + var MyMap = DefineMap.extend({ seal: false }, {}); + var instance = new MyMap({ foo: 'bar' }); + equal(instance.foo, 'bar'); + }); + QUnit.test('set an already initialized null property', function () { + var map = new DefineMap({ foo: null }); + map.assign({ foo: null }); + equal(map.foo, null); + }); + QUnit.test('creating a new key doesn\'t cause two changes', 1, function () { + var map = new DefineMap(); + var oi = new Observation(function () { + return map.serialize(); + }); + canReflect.onValue(oi, function (newVal) { + QUnit.deepEqual(newVal, { a: 1 }, 'updated right'); + }); + map.set('a', 1); + }); + QUnit.test('setting nested object', function () { + var m = new DefineMap({}); + m.assign({ foo: {} }); + m.assign({ foo: {} }); + QUnit.deepEqual(m.get(), { foo: {} }); + }); + QUnit.test('passing a DefineMap to DefineMap (#33)', function () { + var MyMap = DefineMap.extend({ foo: 'observable' }); + var m = new MyMap({ + foo: {}, + bar: {} + }); + var m2 = new MyMap(m); + QUnit.deepEqual(m.get(), m2.get()); + QUnit.ok(m.foo === m2.foo, 'defined props the same'); + QUnit.ok(m.bar === m2.bar, 'expando props the same'); + }); + QUnit.test('serialize: function works (#38)', function () { + var Something = DefineMap.extend({}); + var MyMap = DefineMap.extend({ + somethingRef: { + type: function (val) { + return new Something({ id: val }); + }, + serialize: function (val) { + return val.id; + } + }, + somethingElseRef: { + type: function (val) { + return new Something({ id: val }); + }, + serialize: false + } + }); + var myMap = new MyMap({ + somethingRef: 2, + somethingElseRef: 3 + }); + QUnit.ok(myMap.somethingRef instanceof Something); + QUnit.deepEqual(myMap.serialize(), { somethingRef: 2 }, 'serialize: function and serialize: false works'); + var MyMap2 = DefineMap.extend({ + '*': { + serialize: function (value) { + return '' + value; + } + } + }); + var myMap2 = new MyMap2({ + foo: 1, + bar: 2 + }); + QUnit.deepEqual(myMap2.serialize(), { + foo: '1', + bar: '2' + }, 'serialize: function on default works'); + }); + QUnit.test('get will not create properties', function () { + var method = function () { + }; + var MyMap = DefineMap.extend({ method: method }); + var m = new MyMap(); + m.get('foo'); + QUnit.equal(m.get('method'), method); + }); + QUnit.test('Properties are enumerable', function () { + QUnit.expect(4); + var VM = DefineMap.extend({ foo: 'string' }); + var vm = new VM({ + foo: 'bar', + baz: 'qux' + }); + var i = 0; + canReflect.eachKey(vm, function (value, key) { + if (i === 0) { + QUnit.equal(key, 'foo'); + QUnit.equal(value, 'bar'); + } else { + QUnit.equal(key, 'baz'); + QUnit.equal(value, 'qux'); + } + i++; + }); + }); + QUnit.test('Getters are not enumerable', function () { + QUnit.expect(2); + var MyMap = DefineMap.extend({ + foo: 'string', + baz: { + get: function () { + return this.foo; + } + } + }); + var map = new MyMap({ foo: 'bar' }); + canReflect.eachKey(map, function (value, key) { + QUnit.equal(key, 'foo'); + QUnit.equal(value, 'bar'); + }); + }); + QUnit.test('extending DefineMap constructor functions (#18)', function () { + var AType = DefineMap.extend('AType', { + aProp: {}, + aMethod: function () { + } + }); + var BType = AType.extend('BType', { + bProp: {}, + bMethod: function () { + } + }); + var CType = BType.extend('CType', { + cProp: {}, + cMethod: function () { + } + }); + var map = new CType(); + map.on('aProp', function (ev, newVal, oldVal) { + QUnit.equal(newVal, 'PROP'); + QUnit.equal(oldVal, undefined); + }); + map.on('bProp', function (ev, newVal, oldVal) { + QUnit.equal(newVal, 'FOO'); + QUnit.equal(oldVal, undefined); + }); + map.on('cProp', function (ev, newVal, oldVal) { + QUnit.equal(newVal, 'BAR'); + QUnit.equal(oldVal, undefined); + }); + map.aProp = 'PROP'; + map.bProp = 'FOO'; + map.cProp = 'BAR'; + QUnit.ok(map.aMethod); + QUnit.ok(map.bMethod); + QUnit.ok(map.cMethod); + }); + QUnit.test('extending DefineMap constructor functions more than once (#18)', function () { + var AType = DefineMap.extend('AType', { + aProp: {}, + aMethod: function () { + } + }); + var BType = AType.extend('BType', { + bProp: {}, + bMethod: function () { + } + }); + var CType = AType.extend('CType', { + cProp: {}, + cMethod: function () { + } + }); + var map1 = new BType(); + var map2 = new CType(); + map1.on('aProp', function (ev, newVal, oldVal) { + QUnit.equal(newVal, 'PROP', 'aProp newVal on map1'); + QUnit.equal(oldVal, undefined); + }); + map1.on('bProp', function (ev, newVal, oldVal) { + QUnit.equal(newVal, 'FOO', 'bProp newVal on map1'); + QUnit.equal(oldVal, undefined); + }); + map2.on('aProp', function (ev, newVal, oldVal) { + QUnit.equal(newVal, 'PROP', 'aProp newVal on map2'); + QUnit.equal(oldVal, undefined); + }); + map2.on('cProp', function (ev, newVal, oldVal) { + QUnit.equal(newVal, 'BAR', 'cProp newVal on map2'); + QUnit.equal(oldVal, undefined); + }); + map1.aProp = 'PROP'; + map1.bProp = 'FOO'; + map2.aProp = 'PROP'; + map2.cProp = 'BAR'; + QUnit.ok(map1.aMethod, 'map1 aMethod'); + QUnit.ok(map1.bMethod); + QUnit.ok(map2.aMethod); + QUnit.ok(map2.cMethod, 'map2 cMethod'); + }); + QUnit.test('extending DefineMap constructor functions - value (#18)', function () { + var AType = DefineMap.extend('AType', { aProp: { default: 1 } }); + var BType = AType.extend('BType', {}); + var CType = BType.extend('CType', {}); + var c = new CType(); + QUnit.equal(c.aProp, 1, 'got initial value'); + }); + QUnit.test('copying DefineMap excludes constructor', function () { + var AType = DefineMap.extend('AType', { aProp: { default: 1 } }); + var a = new AType(); + var b = assign({}, a); + QUnit.notEqual(a.constructor, b.constructor, 'Constructor prop not copied'); + QUnit.equal(a.aProp, b.aProp, 'Other values are unaffected'); + }); + QUnit.test('cloning from non-defined map excludes special keys on setup', function () { + var MyType = DefineMap.extend({}); + var a = new MyType({ 'foo': 'bar' }); + var b = new DefineMap(a); + QUnit.notEqual(a.constructor, b.constructor, 'Constructor prop not copied'); + QUnit.notEqual(a._data, b._data, '_data prop not copied'); + QUnit.equal(a.foo, b.foo, 'Other props copied'); + }); + QUnit.test('copying from .set() excludes special keys', function () { + var MyType = DefineMap.extend({}); + var a = new MyType({ + 'foo': 'bar', + 'existing': 'newVal' + }); + var b = new DefineMap({ 'existing': 'oldVal' }); + b.assign(a); + QUnit.notEqual(a.constructor, b.constructor, 'Constructor prop not copied'); + QUnit.notEqual(a._data, b._data, '_data prop not copied'); + QUnit.equal(a.foo, b.foo, 'NEw props copied'); + }); + QUnit.test('copying with assign() excludes special keys', function () { + var a = { + _data: {}, + 'foo': 'bar', + 'existing': 'neVal' + }; + var b = new DefineMap({ 'existing': 'oldVal' }, false); + canReflect.assignMap(b, a); + QUnit.notEqual(a._data, b._data, '_data prop not copied'); + QUnit.equal(a.foo, b.foo, 'New props copied'); + QUnit.equal(a.existing, b.existing, 'Existing props copied'); + }); + QUnit.test('shorthand getter setter (#56)', function () { + var Person = DefineMap.extend({ + first: '*', + last: '*', + get fullName() { + return this.first + ' ' + this.last; + }, + set fullName(newVal) { + var parts = newVal.split(' '); + this.first = parts[0]; + this.last = parts[1]; + } + }); + var p = new Person({ + first: 'Mohamed', + last: 'Cherif' + }); + p.on('fullName', function (ev, newVal, oldVal) { + QUnit.equal(oldVal, 'Mohamed Cherif'); + QUnit.equal(newVal, 'Justin Meyer'); + }); + equal(p.fullName, 'Mohamed Cherif', 'fullName initialized right'); + p.fullName = 'Justin Meyer'; + }); + QUnit.test('compute props can be set to null or undefined (#2372)', function () { + var VM = DefineMap.extend({ computeProp: { type: 'compute' } }); + var vmNull = new VM({ computeProp: null }); + QUnit.equal(vmNull.get('computeProp'), null, 'computeProp is null, no error thrown'); + var vmUndef = new VM({ computeProp: undefined }); + QUnit.equal(vmUndef.get('computeProp'), undefined, 'computeProp is undefined, no error thrown'); + }); + QUnit.test('Inheriting DefineMap .set doesn\'t work if prop is on base map (#74)', function () { + var Base = DefineMap.extend({ baseProp: 'string' }); + var Inheriting = Base.extend(); + var inherting = new Inheriting(); + inherting.set('baseProp', 'value'); + QUnit.equal(inherting.baseProp, 'value', 'set prop'); + }); + if (sealWorks && System.env.indexOf('production') < 0) { + QUnit.test('setting not defined property', function () { + var MyMap = DefineMap.extend({ prop: {} }); + var mymap = new MyMap(); + try { + mymap.notdefined = 'value'; + ok(false, 'no error'); + } catch (e) { + ok(true, 'error thrown'); + } + }); + } + QUnit.test('.extend errors when re-defining a property (#117)', function () { + var A = DefineMap.extend('A', { + foo: { + type: 'string', + default: 'blah' + } + }); + A.extend('B', { + foo: { + type: 'string', + default: 'flub' + } + }); + var C = DefineMap.extend('C', { + foo: { + get: function () { + return 'blah'; + } + } + }); + C.extend('D', { + foo: { + get: function () { + return 'flub'; + } + } + }); + QUnit.ok(true, 'extended without errors'); + }); + QUnit.test('.value functions should not be observable', function () { + var outer = new DefineMap({ bam: 'baz' }); + var ItemsVM = DefineMap.extend({ + item: { + default: function () { + (function () { + }(this.zed, outer.bam)); + return new DefineMap({ foo: 'bar' }); + } + }, + zed: 'string' + }); + var items = new ItemsVM(); + var count = 0; + var itemsList = new Observation(function () { + count++; + return items.item; + }); + canReflect.onValue(itemsList, function () { + }); + items.item.foo = 'changed'; + items.zed = 'changed'; + equal(count, 1); + }); + QUnit.test('.value values are overwritten by props in DefineMap construction', function () { + var Foo = DefineMap.extend({ bar: { default: 'baz' } }); + var foo = new Foo({ bar: 'quux' }); + equal(foo.bar, 'quux', 'Value set properly'); + }); + QUnit.test('can-reflect reflections work with DefineMap', function () { + var b = new DefineMap({ 'foo': 'bar' }); + var c = new (DefineMap.extend({ + 'baz': { + get: function () { + return b.foo; + } + } + }))({ + 'foo': 'bar', + thud: 'baz' + }); + QUnit.equal(canReflect.getKeyValue(b, 'foo'), 'bar', 'unbound value'); + var handler = function (newValue) { + QUnit.equal(newValue, 'quux', 'observed new value'); + canReflect.offKeyValue(c, 'baz', handler); + }; + QUnit.ok(!canReflect.isValueLike(c), 'isValueLike is false'); + QUnit.ok(canReflect.isObservableLike(c), 'isObservableLike is true'); + QUnit.ok(canReflect.isMapLike(c), 'isMapLike is true'); + QUnit.ok(!canReflect.isListLike(c), 'isListLike is false'); + QUnit.ok(!canReflect.keyHasDependencies(b, 'foo'), 'keyHasDependencies -- false'); + canReflect.onKeyValue(c, 'baz', handler); + canReflect.onKeyValue(c, 'thud', handler); + QUnit.ok(canReflect.keyHasDependencies(c, 'baz'), 'keyHasDependencies -- true'); + b.foo = 'quux'; + c.thud = 'quux'; + QUnit.equal(canReflect.getKeyValue(c, 'baz'), 'quux', 'bound value'); + b.foo = 'thud'; + c.baz = 'jeek'; + }); + QUnit.test('can-reflect setKeyValue', function () { + var a = new DefineMap({ 'a': 'b' }); + canReflect.setKeyValue(a, 'a', 'c'); + QUnit.equal(a.a, 'c', 'setKeyValue'); + }); + QUnit.test('can-reflect deleteKeyValue', function () { + var a = new DefineMap({ 'a': 'b' }); + canReflect.deleteKeyValue(a, 'a'); + QUnit.equal(a.a, undefined, 'value is now undefined'); + QUnit.ok(!('a' in a.get()), 'value not included in serial'); + }); + QUnit.test('can-reflect getKeyDependencies', function () { + var a = new DefineMap({ 'a': 'a' }); + var b = new (DefineMap.extend({ + 'a': { + get: function () { + return a.a; + } + } + }))(); + ok(canReflect.getKeyDependencies(b, 'a'), 'dependencies exist'); + ok(!canReflect.getKeyDependencies(b, 'b'), 'no dependencies exist for unknown value'); + ok(canReflect.getKeyDependencies(b, 'a').valueDependencies.has(b._computed.a.compute), 'dependencies returned'); + }); + QUnit.test('can-reflect assign', function () { + var aData = { 'a': 'b' }; + var bData = { 'b': 'c' }; + var a = new DefineMap(aData); + var b = new DefineMap(bData); + canReflect.assign(a, b); + QUnit.deepEqual(a.get(), assign(aData, bData), 'when called with an object, should merge into existing object'); + }); + QUnit.test('Does not attempt to redefine _data if already defined', function () { + var Bar = DefineMap.extend({ seal: false }, { baz: { default: 'thud' } }); + var baz = new Bar(); + define(baz, { + quux: { default: 'jeek' }, + plonk: { + get: function () { + return 'waldo'; + } + } + }, baz._define); + QUnit.equal(baz.quux, 'jeek', 'New definitions successful'); + QUnit.equal(baz.plonk, 'waldo', 'New computed definitions successful'); + QUnit.equal(baz.baz, 'thud', 'Old definitions still available'); + }); + if (!System.isEnv('production')) { + QUnit.test('redefines still not allowed on sealed objects', function () { + QUnit.expect(6); + var Bar = DefineMap.extend({ seal: true }, { baz: { default: 'thud' } }); + var baz = new Bar(); + try { + define(baz, { quux: { default: 'jeek' } }, baz._define); + } catch (e) { + QUnit.ok(/is not extensible/i.test(e.message), 'Sealed object throws on data property defines'); + QUnit.ok(!Object.getOwnPropertyDescriptor(baz, 'quux'), 'nothing set on object'); + QUnit.ok(!Object.getOwnPropertyDescriptor(baz._data, 'quux'), 'nothing set on _data'); + } + try { + define(baz, { + plonk: { + get: function () { + return 'waldo'; + } + } + }, baz._define); + } catch (e) { + QUnit.ok(/is not extensible/i.test(e.message), 'Sealed object throws on computed property defines'); + QUnit.ok(!Object.getOwnPropertyDescriptor(baz, 'plonk'), 'nothing set on object'); + QUnit.ok(!Object.getOwnPropertyDescriptor(baz._computed, 'plonk'), 'nothing set on _computed'); + } + }); + } + QUnit.test('Call .get() when a nested object has its own get method', function () { + var Bar = DefineMap.extend({ request: '*' }); + var request = { + prop: 22, + get: function () { + if (arguments.length === 0) { + throw new Error('This function can\'t be called with 0 arguments'); + } + } + }; + var obj = new Bar({ request: request }); + var data = obj.get(); + QUnit.equal(data.request.prop, 22, 'obj did get()'); + }); + QUnit.test('DefineMap short-hand Type (#221)', function () { + var Child = DefineMap.extend('child', { other: DefineMap }); + var c = new Child(); + c.other = { prop: 'hello' }; + QUnit.ok(c.other instanceof DefineMap, 'is a DefineMap'); + }); + QUnit.test('non-Object constructor', function () { + var Constructor = DefineMap.extend(); + QUnit.ok(!isPlainObject(new DefineMap()), 'instance of DefineMap is not a plain object'); + QUnit.ok(!isPlainObject(new Constructor()), 'instance of extended DefineMap is not a plain object'); + }); + QUnit.test('Observation bound to getter using lastSetVal updates correctly (canjs#3541)', function () { + var MyMap = DefineMap.extend({ + foo: { + get: function (lastSetVal) { + if (lastSetVal) { + return lastSetVal; + } + } + } + }); + var map = new MyMap(); + var oi = new Observation(function () { + return map.get('foo'); + }); + canReflect.onValue(oi, function (newVal) { + QUnit.equal(newVal, 'bar', 'updated to bar'); + }); + map.set('foo', 'bar'); + }); + QUnit.test('Observation bound to async getter updates correctly (canjs#3541)', function () { + var MyMap = DefineMap.extend({ + foo: { + get: function (lastSetVal, resolve) { + if (lastSetVal) { + return resolve(lastSetVal); + } + } + } + }); + var map = new MyMap(); + var oi = new Observation(function () { + return map.get('foo'); + }); + canReflect.onValue(oi, function (newVal) { + QUnit.equal(newVal, 'bar', 'updated to bar'); + }); + map.set('foo', 'bar'); + }); + canTestHelpers.devOnlyTest('log all property changes', function (assert) { + var done = assert.async(); + var Person = DefineMap.extend({ + first: 'string', + last: 'string', + children: { Type: DefineList }, + fullName: { + get: function () { + return this.first + ' ' + this.last; + } + } + }); + var changed = []; + var log = dev.log; + dev.log = function () { + changed.push(JSON.parse(arguments[2])); + }; + var p = new Person(); + p.log(); + p.on('fullName', function () { + }); + p.first = 'Manuel'; + p.last = 'Mujica'; + assert.expect(1); + setTimeout(function () { + dev.log = log; + assert.deepEqual(changed, [ + 'first', + 'fullName', + 'last', + 'fullName' + ], 'should log all property changes'); + done(); + }); + }); + canTestHelpers.devOnlyTest('log single property changes', function (assert) { + var done = assert.async(); + var Person = DefineMap.extend({ + first: 'string', + last: 'string', + age: 'number' + }); + var changed = []; + var log = dev.log; + dev.log = function () { + changed.push(JSON.parse(arguments[2])); + }; + var p = new Person(); + p.log('first'); + p.first = 'John'; + p.last = 'Doe'; + p.age = 99; + assert.expect(1); + setTimeout(function () { + dev.log = log; + assert.deepEqual(changed, ['first'], 'should log \'first\' changes'); + done(); + }); + }); + canTestHelpers.devOnlyTest('log multiple property changes', function (assert) { + var done = assert.async(); + var Person = DefineMap.extend({ + first: 'string', + last: 'string', + age: 'number', + company: 'string' + }); + var changed = []; + var log = dev.log; + dev.log = function () { + changed.push(JSON.parse(arguments[2])); + }; + var p = new Person(); + p.log('first'); + p.log('age'); + p.first = 'John'; + p.last = 'Doe'; + p.company = 'Bitovi'; + p.age = 99; + assert.expect(1); + setTimeout(function () { + dev.log = log; + assert.deepEqual(changed, [ + 'first', + 'age' + ], 'should log first and age'); + done(); + }); + }); + canTestHelpers.devOnlyTest('Setting a value with an object type generates a warning (#148)', function () { + QUnit.expect(1); + var message = 'can-define: The default value for DefineMap{}.options is set to an object. This will be shared by all instances of the DefineMap. Use a function that returns the object instead.'; + var finishErrorCheck = canTestHelpers.willWarn(message); + DefineMap.extend({ options: { default: {} } }); + DefineMap.extend({ options: { default: [] } }); + DefineMap.extend({ + options: { + default: function () { + } + } + }); + DefineMap.extend({ options: { default: 2 } }); + QUnit.equal(finishErrorCheck(), 2); + }); + canTestHelpers.devOnlyTest('Setting a default value to a constructor type generates a warning', function () { + QUnit.expect(1); + var message = 'can-define: The "default" for DefineMap{}.options is set to a constructor. Did you mean "Default" instead?'; + var finishErrorCheck = canTestHelpers.willWarn(message); + DefineMap.extend({ options: { default: DefineMap } }); + QUnit.equal(finishErrorCheck(), 1); + }); + canTestHelpers.devOnlyTest('can.getName symbol behavior', function (assert) { + var getName = function (instance) { + return instance[canSymbol.for('can.getName')](); + }; + assert.ok('DefineMap{}', getName(new DefineMap()), 'should use DefineMap constructor name by default'); + var MyMap = DefineMap.extend('MyMap', {}); + assert.ok('MyMap{}', getName(new MyMap()), 'should use custom map name when provided'); + }); + canTestHelpers.devOnlyTest('Error on not using a constructor or string on short-hand definitions (#278)', function () { + expect(5); + var message = /does not match a supported propDefinition. See: https:\/\/canjs.com\/doc\/can-define.types.propDefinition.html/i; + var finishErrorCheck = canTestHelpers.willError(message, function (actual, match) { + var rightProp = /prop0[15]/; + QUnit.ok(rightProp.test(actual.split(' ')[0])); + QUnit.ok(match); + }); + DefineMap.extend('ShortName', { + prop01: 0, + prop02: function () { + }, + prop03: 'string', + prop04: DefineMap, + prop05: 'a string that is not a type', + prop06: [], + get prop07() { + }, + set prop07(newVal) { + }, + prop08: 'boolean' + }); + QUnit.equal(finishErrorCheck(), 2); + }); + QUnit.test('Improper shorthand properties are not set', function () { + var VM = DefineMap.extend({ + prop01: 0, + prop02: function () { + }, + prop03: 'some random string' + }); + QUnit.equal(VM.prototype._define.methods.prop01, undefined); + QUnit.equal(typeof VM.prototype._define.methods.prop02, 'function'); + QUnit.equal(VM.prototype._define.methods.prop03, undefined); + }); + QUnit.test('onKeyValue sets up computed values', function () { + var fullNameCalls = []; + var VM = DefineMap.extend({ + first: 'string', + last: 'string', + get fullName() { + fullNameCalls.push(this.first + ' ' + this.last); + return this.first + ' ' + this.last; + } + }); + var vm = new VM({ + first: 'J', + last: 'M' + }); + canReflect.onKeyValue(vm, 'fullName', function () { + }); + QUnit.deepEqual(fullNameCalls, ['J M']); + }); + QUnit.test('async getters derived from other properties should have correct keyDependencies', function () { + var VM = DefineMap.extend({ + get source() { + return 'source value'; + }, + derived: { + get: function (last, resolve) { + return resolve(this.source); + } + } + }); + var vm = new VM(); + vm.on('derived', function () { + }); + QUnit.ok(vm._computed.derived.compute.observation.newDependencies.keyDependencies.get(vm).has('source'), 'getter should depend on vm.source'); + }); + var sealDoesErrorWithPropertyName = function () { + 'use strict'; + var o = Object.seal({}); + try { + o.foo = 'bar'; + } catch (error) { + return error.message.indexOf('foo') !== -1; + } + return false; + }(); + canTestHelpers.devOnlyTest('setting a property gives a nice error', function () { + var VM = DefineMap.extend({}); + var vm = new VM(); + try { + vm.set('fooxyz', 'bar'); + } catch (error) { + if (sealDoesErrorWithPropertyName) { + QUnit.ok(error.message.indexOf('fooxyz') !== -1, 'Set property error with property name should be thrown'); + } else { + QUnit.ok(true, 'Set property error should be thrown'); + } + } + }); + canTestHelpers.devOnlyTest('can.hasKey and can.hasOwnKey (#303)', function (assert) { + var hasKeySymbol = canSymbol.for('can.hasKey'), hasOwnKeySymbol = canSymbol.for('can.hasOwnKey'); + var Parent = DefineMap.extend({ + parentProp: 'any', + get parentDerivedProp() { + if (this.parentProp) { + return 'parentDerived'; + } + } + }); + var VM = Parent.extend({ + prop: 'any', + get derivedProp() { + if (this.prop) { + return 'derived'; + } + } + }); + var vm = new VM(); + assert.equal(vm[hasKeySymbol]('prop'), true, 'vm.hasKey(\'prop\') true'); + assert.equal(vm[hasKeySymbol]('derivedProp'), true, 'vm.hasKey(\'derivedProp\') true'); + assert.equal(vm[hasKeySymbol]('parentProp'), true, 'vm.hasKey(\'parentProp\') true'); + assert.equal(vm[hasKeySymbol]('parentDerivedProp'), true, 'vm.hasKey(\'parentDerivedProp\') true'); + assert.equal(vm[hasKeySymbol]('anotherProp'), false, 'vm.hasKey(\'anotherProp\') false'); + assert.equal(vm[hasOwnKeySymbol]('prop'), true, 'vm.hasOwnKey(\'prop\') true'); + assert.equal(vm[hasOwnKeySymbol]('derivedProp'), true, 'vm.hasOwnKey(\'derivedProp\') true'); + assert.equal(vm[hasOwnKeySymbol]('parentProp'), false, 'vm.hasOwnKey(\'parentProp\') false'); + assert.equal(vm[hasOwnKeySymbol]('parentDerivedProp'), false, 'vm.hasOwnKey(\'parentDerivedProp\') false'); + assert.equal(vm[hasOwnKeySymbol]('anotherProp'), false, 'vm.hasOwnKey(\'anotherProp\') false'); + }); + canTestHelpers.devOnlyTest('getOwnKeys, getOwnEnumerableKeys (#326)', function (assert) { + var getOwnEnumerableKeysSymbol = canSymbol.for('can.getOwnEnumerableKeys'), getOwnKeysSymbol = canSymbol.for('can.getOwnKeys'); + var Parent = DefineMap.extend({ + parentProp: 'any', + get parentDerivedProp() { + if (this.parentProp) { + return 'parentDerived'; + } + }, + parentValueProp: { + value: function (prop) { + if (this.parentProp) { + prop.resolve(this.parentProp); + } + prop.listenTo('parentProp', prop.resolve); + } + } + }); + var VM = Parent.extend({ + prop: 'any', + get derivedProp() { + if (this.prop) { + return 'derived'; + } + }, + valueProp: { + value: function (prop) { + if (this.prop) { + prop.resolve(this.prop); + } + prop.listenTo('prop', prop.resolve); + } + } + }); + var vm = new VM(); + assert.deepEqual(vm[getOwnEnumerableKeysSymbol](), [ + 'prop', + 'valueProp', + 'parentProp', + 'parentValueProp' + ], 'vm.getOwnEnumerableKeys()'); + assert.deepEqual(vm[getOwnKeysSymbol](), [ + 'prop', + 'valueProp', + 'parentProp', + 'parentValueProp', + 'derivedProp', + 'parentDerivedProp' + ], 'vm.getOwnKeys()'); + }); + QUnit.test('value as a string breaks', function () { + var MyMap = DefineMap.extend({ prop: { value: 'a string' } }); + var my = new MyMap(); + QUnit.equal(my.prop, 'a string', 'works'); + }); + QUnit.test('canReflect.getSchema', function () { + var MyType = DefineMap.extend({ + id: { + identity: true, + type: 'number' + }, + name: 'string', + foo: { serialize: false } + }); + var schema = canReflect.getSchema(MyType); + QUnit.deepEqual(schema.identity, ['id'], 'right identity'); + QUnit.deepEqual(Object.keys(schema.keys), [ + 'id', + 'name' + ], 'right key names'); + QUnit.equal(canReflect.convert('1', schema.keys.id), 1, 'converted to number'); + QUnit.equal(canReflect.convert(3, schema.keys.id), '3', 'converted to number'); + }); + QUnit.test('use can.new and can.serialize for conversion', function () { + var Status = canReflect.assignSymbols({}, { + 'can.new': function (val) { + return val.toLowerCase(); + }, + 'can.getSchema': function () { + return { + type: 'Or', + values: [ + 'new', + 'assigned', + 'complete' + ] + }; + }, + 'can.serialize': function () { + return this.toUpperCase(); + } + }); + var Todo = DefineMap.extend('Todo', { status: Status }); + var todo = new Todo({ status: 'NEW' }); + QUnit.equal(todo.status, 'new', 'converted during set'); + QUnit.deepEqual(todo.serialize(), { status: 'NEW' }, 'serialized to upper case'); + var Todo2 = DefineMap.extend('Todo', { due: 'date' }); + var date = new Date(2018, 3, 30); + var todo2 = new Todo2({ due: date.toString() }); + QUnit.ok(todo2.due instanceof Date, 'converted to a date instance'); + var res = todo2.serialize(); + QUnit.deepEqual(res, { due: date }, 'serialized to a date?'); + }); + QUnit.test('make sure stringOrObservable works', function () { + var Type = DefineMap.extend({ val: 'stringOrObservable' }); + var type = new Type({ val: 'foo' }); + QUnit.equal(type.val, 'foo', 'works'); + }); + QUnit.test('primitive types work with val: Type', function () { + var UpperCase = {}; + UpperCase[canSymbol.for('can.new')] = function (val) { + return val.toUpperCase(); + }; + var Type = DefineMap.extend({ val: UpperCase }); + var type = new Type({ val: 'works' }); + QUnit.equal(type.val, 'WORKS', 'it worked'); + }); + QUnit.test('primitive types work with val: {Type: Type}', function () { + var UpperCase = {}; + UpperCase[canSymbol.for('can.new')] = function (val) { + return val.toUpperCase(); + }; + var Type = DefineMap.extend({ val: { Type: UpperCase } }); + var type = new Type({ val: 'works' }); + QUnit.equal(type.val, 'WORKS', 'it worked'); + }); + QUnit.test('primitive types work with val: {type: Type}', function () { + var UpperCase = {}; + UpperCase[canSymbol.for('can.new')] = function (val) { + return val.toUpperCase(); + }; + var Type = DefineMap.extend({ val: { type: UpperCase } }); + var type = new Type({ val: 'works' }); + QUnit.equal(type.val, 'WORKS', 'it worked'); + }); + QUnit.test('ownKeys works on basic DefineMaps', function () { + var map = new DefineMap({ + first: 'Jane', + last: 'Doe' + }); + var keys = canReflect.getOwnKeys(map); + QUnit.equal(keys.length, 2, 'There are 2 keys'); + }); + QUnit.test('deleteKey works (#351)', function () { + var map = new DefineMap({ foo: 'bar' }); + QUnit.deepEqual(canReflect.getOwnKeys(map), ['foo']); + map.set('zed', 'ted'); + QUnit.deepEqual(canReflect.getOwnKeys(map), [ + 'foo', + 'zed' + ]); + map.deleteKey('zed'); + QUnit.deepEqual(canReflect.getOwnKeys(map), ['foo']); + map.deleteKey('foo'); + QUnit.deepEqual(canReflect.getOwnKeys(map), []); + map.set('foo', 'bar'); + map = new DefineMap({ foo: 'bar' }, true); + map.deleteKey('foo'); + QUnit.equal(map.foo, undefined, 'prop set to undefined'); + }); + QUnit.test('makes sure observation add is called (#393)', function () { + var map = new DefineMap({ foo: 'bar' }); + canReflect.deleteKeyValue(map, 'foo'); + ObservationRecorder.start(); + (function () { + return map.foo; + }()); + var result = ObservationRecorder.stop(); + QUnit.deepEqual(canReflect.toArray(result.keyDependencies.get(map)), ['foo'], 'toArray'); + }); + QUnit.test('type called with `this` as the map (#349)', function () { + var Type = DefineMap.extend({ + foo: { + type: function () { + QUnit.equal(Type, this.constructor, 'got the right this'); + return 5; + }, + default: 4 + } + }); + var map = new Type(); + QUnit.equal(map.foo, 5); + }); + QUnit.test('expandos use default type (#383)', function () { + var AllNumbers = DefineMap.extend({ '*': { type: 'number' } }); + var someNumbers = new AllNumbers({ version: '24' }); + QUnit.ok(someNumbers.version === 24, 'is 24'); + }); + QUnit.test('do not enumerate anything other than key properties (#369)', function () { + var ancestor = { prop: true }; + var F = function () { + }; + F.prototype = ancestor; + var descendant = new F(); + Object.defineProperty(descendant, 'prop', { + writable: true, + configurable: true, + enumerable: false, + value: true + }); + var test = {}; + for (var k in descendant) { + test[k] = descendant[k]; + } + if (test.prop) { + return QUnit.ok(test.prop, 'Browser doesn\'t correctly skip shadowed enumerable properties'); + } + var Type = DefineMap.extend({ + aProp: 'string', + aMethod: function () { + } + }); + var instance = new Type({ + aProp: 'VALUE', + anExpando: 'VALUE' + }); + var props = {}; + for (var prop in instance) { + props[prop] = true; + } + QUnit.deepEqual(props, { + aProp: true, + anExpando: true, + aMethod: true + }); + }); + QUnit.test('Properties added via defineInstanceKey are observable', function () { + var Type = DefineMap.extend({}); + var map = new Type(); + var obs = new Observation(function () { + return canReflect.serialize(map); + }); + var count = 0; + canReflect.onValue(obs, function (val) { + count++; + if (count === 2) { + QUnit.deepEqual(val, { foo: 'bar' }, 'changed value'); + } + }); + canReflect.defineInstanceKey(Type, 'foo', { type: 'string' }); + map.foo = 'bar'; + }); + QUnit.test('Serialized computes do not prevent getters from working', function () { + var Type = DefineMap.extend('MyType', { + page: 'string', + myPage: { + get: function (last, resolve) { + return this.page; + } + } + }); + var first = new Type({ page: 'one' }); + var firstObservation = new Observation(function () { + return canReflect.serialize(first); + }); + var boundTo = Function.prototype; + canReflect.onValue(firstObservation, boundTo); + var second = new Type({ page: 'two' }); + QUnit.equal(second.myPage, 'two', 'Runs the getter correctly'); + }); + QUnit.test('setup should be called (#395)', function () { + var calls = []; + var Base = DefineMap.extend('Base', { + setup: function (attrs) { + calls.push(this); + return DefineMap.prototype.setup.apply(this, arguments); + } + }); + var Super = Base.extend('Super', {}); + var base = new Base(); + var supa = new Super(); + QUnit.deepEqual(calls, [ + base, + supa + ], 'setup called'); + }); +}); +/*can-define@2.7.1#test/test-list-and-map*/ +define('can-define@2.7.1#test/test-list-and-map', [ + 'require', + 'exports', + 'module', + 'can-define/map/map', + 'can-define/list/list', + 'can-reflect', + 'can-observation', + 'can-define', + 'steal-qunit' +], function (require, exports, module) { + var DefineMap = require('can-define/map/map'); + var DefineList = require('can-define/list/list'); + var canReflect = require('can-reflect'); + var isPlainObject = canReflect.isPlainObject; + var Observation = require('can-observation'); + var define = require('can-define'); + var QUnit = require('steal-qunit'); + QUnit.module('can-define: map and list combined'); + QUnit.test('basics', function () { + var items = new DefineMap({ + people: [ + { name: 'Justin' }, + { name: 'Brian' } + ], + count: 1000 + }); + QUnit.ok(items.people instanceof DefineList, 'people is list'); + QUnit.ok(items.people.item(0) instanceof DefineMap, '1st object is Map'); + QUnit.ok(items.people.item(1) instanceof DefineMap, '2nd object is Map'); + QUnit.equal(items.people.item(1).name, 'Brian', '2nd object\'s name is right'); + QUnit.equal(items.count, 1000, 'count is number'); + }); + QUnit.test('basic type', function () { + QUnit.expect(6); + var Typer = function (arrayWithAddedItem, listWithAddedItem) { + this.arrayWithAddedItem = arrayWithAddedItem; + this.listWithAddedItem = listWithAddedItem; + }; + define(Typer.prototype, { + arrayWithAddedItem: { + type: function (value) { + if (value && value.push) { + value.push('item'); + } + return value; + } + }, + listWithAddedItem: { + type: function (value) { + if (value && value.push) { + value.push('item'); + } + return value; + }, + Type: DefineList + } + }); + var t = new Typer(); + deepEqual(Object.keys(t), [], 'no keys'); + var array = []; + t.arrayWithAddedItem = array; + deepEqual(array, ['item'], 'updated array'); + QUnit.equal(t.arrayWithAddedItem, array, 'leave value as array'); + t.listWithAddedItem = []; + QUnit.ok(t.listWithAddedItem instanceof DefineList, 'convert to CanList'); + QUnit.equal(t.listWithAddedItem[0], 'item', 'has item in it'); + var observation = new Observation(function () { + return t.listWithAddedItem.attr('length'); + }); + canReflect.onValue(observation, function (newVal) { + QUnit.equal(newVal, 2, 'got a length change'); + }); + t.listWithAddedItem.push('another item'); + }); + QUnit.test('serialize works', function () { + var Person = DefineMap.extend({ + first: 'string', + last: 'string' + }); + var People = DefineList.extend({ '*': Person }); + var people = new People([{ + first: 'j', + last: 'm' + }]); + QUnit.deepEqual(people.serialize(), [{ + first: 'j', + last: 'm' + }]); + }); + QUnit.test('Extended Map with empty def converts to default Observables', function () { + var School = DefineMap.extend({ + students: {}, + teacher: {} + }); + var school = new School(); + school.students = [{ name: 'J' }]; + school.teacher = { name: 'M' }; + ok(school.students instanceof DefineList, 'converted to DefineList'); + ok(school.teacher instanceof DefineMap, 'converted to DefineMap'); + }); + QUnit.test('default \'observable\' type prevents Type from working (#29)', function () { + var M = DefineMap.extend('M', { id: 'number' }); + var L = DefineList.extend('L', { '*': M }); + var MyMap = DefineMap.extend({ l: L }); + var m = new MyMap({ l: [{ id: 5 }] }); + QUnit.ok(m.l[0] instanceof M, 'is instance'); + QUnit.equal(m.l[0].id, 5, 'correct props'); + }); + QUnit.test('inline DefineList Type', function () { + var M = DefineMap.extend('M', { id: 'number' }); + var MyMap = DefineMap.extend({ l: { Type: [M] } }); + var m = new MyMap({ l: [{ id: 5 }] }); + QUnit.ok(m.l[0] instanceof M, 'is instance'); + QUnit.equal(m.l[0].id, 5, 'correct props'); + }); + QUnit.test('recursively `get`s (#31)', function () { + var M = DefineMap.extend('M', { id: 'number' }); + var MyMap = DefineMap.extend({ l: { Type: [M] } }); + var m = new MyMap({ l: [{ id: 5 }] }); + var res = m.get(); + QUnit.ok(Array.isArray(res.l), 'is a plain array'); + QUnit.ok(isPlainObject(res.l[0]), 'plain object'); + }); + QUnit.test('DefineList trigger deprecation warning when set with Map.set (#93)', 0, function () { + var map = new DefineMap({ things: [{ foo: 'bar' }] }); + map.things.attr = function () { + ok(false, 'attr should not be called'); + }; + map.assign({ things: [{ baz: 'luhrmann' }] }); + }); + test('Value generator can read other properties', function () { + var Map = define.Constructor({ + letters: { default: 'ABC' }, + numbers: { + default: [ + 1, + 2, + 3 + ] + }, + definedLetters: { default: 'DEF' }, + definedNumbers: { + default: [ + 4, + 5, + 6 + ] + }, + generatedLetters: { + default: function () { + return 'GHI'; + } + }, + generatedNumbers: { + default: function () { + return new DefineList([ + 7, + 8, + 9 + ]); + } + }, + firstLetter: { + default: function () { + return this.letters.substr(0, 1); + } + }, + firstNumber: { + default: function () { + return this.numbers[0]; + } + }, + middleLetter: { + default: function () { + return this.definedLetters.substr(1, 1); + } + }, + middleNumber: { + default: function () { + return this.definedNumbers[1]; + } + }, + lastLetter: { + default: function () { + return this.generatedLetters.substr(2, 1); + } + }, + lastNumber: { + default: function () { + return this.generatedNumbers[2]; + } + } + }); + var map = new Map(); + var prefix = 'Was able to read dependent value from '; + equal(map.firstLetter, 'A', prefix + 'traditional can.Map style property definition'); + equal(map.firstNumber, 1, prefix + 'traditional can.Map style property definition'); + equal(map.middleLetter, 'E', prefix + 'define plugin style default property definition'); + equal(map.middleNumber, 5, prefix + 'define plugin style default property definition'); + equal(map.lastLetter, 'I', prefix + 'define plugin style generated default property definition'); + equal(map.lastNumber, 9, prefix + 'define plugin style generated default property definition'); + }); + test('value and get (#1521)', function () { + var MyMap = define.Constructor({ + data: { + default: function () { + return new DefineList(['test']); + } + }, + size: { + default: 1, + get: function (val) { + var list = this.data; + var length = list.attr('length'); + return val + length; + } + } + }); + var map = new MyMap({}); + equal(map.size, 2); + }); + QUnit.test('Assign value on map', function () { + var MyConstruct = DefineMap.extend({ + list: DefineList, + name: 'string' + }); + var obj = new MyConstruct({ + list: [ + 'data', + 'data', + 'data' + ], + name: 'CanJS', + foo: { + bar: 'bar', + zoo: 'say' + } + }); + obj.assign({ + list: ['another'], + foo: { bar: 'zed' } + }); + QUnit.equal(obj.list.length, 1, 'list length should be 1'); + QUnit.propEqual(obj.foo, { bar: 'zed' }, 'foo.bar is set correctly'); + QUnit.equal(obj.name, 'CanJS', 'name is unchanged'); + }); + QUnit.test('Update value on a map', function () { + var MyConstruct = DefineMap.extend({ + list: DefineList, + name: 'string' + }); + var obj = new MyConstruct({ + list: [ + 'data', + 'data', + 'data' + ], + name: 'CanJS', + foo: { bar: 'bar' } + }); + obj.update({ + list: ['another'], + foo: { bar: 'zed' } + }); + QUnit.equal(obj.list.length, 1, 'list length should be 1'); + QUnit.equal(obj.foo.bar, 'zed', 'foo.bar is set correctly'); + QUnit.equal(obj.name, undefined, 'name is removed'); + }); + QUnit.test('Deep assign a map', function () { + var MyConstruct = DefineMap.extend({ + list: DefineList, + name: 'string' + }); + var obj = new MyConstruct({ + list: [ + 'data', + 'data', + 'data' + ], + name: 'Test Name' + }); + QUnit.equal(obj.list.length, 3, 'list length should be 3'); + obj.assignDeep({ list: ['something'] }); + QUnit.equal(obj.name, 'Test Name', 'Name property is still intact'); + QUnit.equal(obj.list[0], 'something', 'the first element in the list should be updated'); + }); + QUnit.test('Deep updating a map', function () { + var MyConstruct = DefineMap.extend({ + list: DefineList, + name: 'string' + }); + var obj = new MyConstruct({ + list: [ + 'data', + 'data', + 'data' + ], + name: 'Test Name' + }); + QUnit.equal(obj.list.length, 3, 'list length should be 3'); + obj.updateDeep({ list: ['something'] }); + QUnit.equal(obj.name, undefined, 'Name property has been reset'); + QUnit.equal(obj.list[0], 'something', 'the first element of the list should be updated'); + }); + QUnit.test('assignDeep', function () { + var justin = new DefineMap({ + name: 'Justin', + age: 35 + }), payal = new DefineMap({ + name: 'Payal', + age: 35 + }); + var people = new DefineList([ + justin, + payal + ]); + people.assignDeep([{ age: 36 }]); + QUnit.deepEqual(people.serialize(), [ + { + name: 'Justin', + age: 36 + }, + { + name: 'Payal', + age: 35 + } + ], 'assigned right'); + }); +}); +/*can-reflect-tests@0.2.1#observables/map-like/type/define-instance-key*/ +define('can-reflect-tests@0.2.1#observables/map-like/type/define-instance-key', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-symbol', + 'can-reflect' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + module.exports = function (name, makeType) { + QUnit.test(name + ' canReflect.defineInstanceKey', function () { + var Type = makeType(); + Type[canSymbol.for('can.defineInstanceKey')]('prop', { + value: 0, + configurable: true, + writable: true, + enumerable: true + }); + var t = new Type(); + QUnit.equal(canReflect.getKeyValue(t, 'prop'), 0, 'default value used'); + canReflect.setKeyValue(t, 'prop', '5'); + t.prop = '5'; + QUnit.equal(t.prop, '5', 'value set'); + }); + }; +}); +/*can-reflect-tests@0.2.1#observables/map-like/type/define-instance-key-enumerable*/ +define('can-reflect-tests@0.2.1#observables/map-like/type/define-instance-key-enumerable', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-symbol', + 'can-reflect' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + module.exports = function (name, makeType) { + QUnit.test(name + ' canReflect.defineInstanceKey with enumerable', function () { + var Type = makeType(); + Type[canSymbol.for('can.defineInstanceKey')]('prop', { + configurable: true, + writable: true, + enumerable: true + }); + Type[canSymbol.for('can.defineInstanceKey')]('nonEnum', { + enumerable: false, + value: 0, + configurable: true, + writable: true + }); + var t = new Type(); + QUnit.equal(canReflect.getKeyValue(t, 'nonEnum'), 0, 'default value used'); + canReflect.setKeyValue(t, 'prop', '5'); + t.prop = '5'; + QUnit.equal(t.prop, '5', 'value set'); + QUnit.deepEqual(canReflect.serialize(t), { prop: '5' }, 'enumerable respected'); + }); + }; +}); +/*can-reflect-tests@0.2.1#observables/map-like/type/on-instance-bound-change*/ +define('can-reflect-tests@0.2.1#observables/map-like/type/on-instance-bound-change', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-symbol', + 'can-reflect' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + module.exports = function (name, makeType) { + QUnit.test(name + ' canReflect.onInstanceBoundChange', function () { + var Type = makeType(); + Type[canSymbol.for('can.defineInstanceKey')]('prop', { + configurable: true, + writable: true, + enumerable: true + }); + var calls = []; + function handler(obj, patches) { + calls.push([ + obj, + patches + ]); + } + Type[canSymbol.for('can.onInstanceBoundChange')](handler); + var instance = new Type({ prop: 'value' }); + var bindHandler = function () { + }; + canReflect.onKeyValue(instance, 'prop', bindHandler); + canReflect.offKeyValue(instance, 'prop', bindHandler); + Type[canSymbol.for('can.offInstanceBoundChange')](handler); + canReflect.onKeyValue(instance, 'prop', bindHandler); + canReflect.offKeyValue(instance, 'prop', bindHandler); + QUnit.deepEqual(calls, [ + [ + instance, + true + ], + [ + instance, + false + ] + ]); + }); + }; +}); +/*can-reflect-tests@0.2.1#observables/map-like/type/on-instance-patches*/ +define('can-reflect-tests@0.2.1#observables/map-like/type/on-instance-patches', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-symbol', + 'can-reflect' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + module.exports = function (name, makeType) { + QUnit.test(name + ' canReflect.onInstancePatches', function () { + var Type = makeType(); + Type[canSymbol.for('can.defineInstanceKey')]('first', { + configurable: true, + writable: true, + enumerable: true + }); + Type[canSymbol.for('can.defineInstanceKey')]('last', { + configurable: true, + writable: true, + enumerable: true + }); + Type[canSymbol.for('can.defineInstanceKey')]('middle', { + configurable: true, + writable: true, + enumerable: true + }); + var calls = []; + function handler(obj, patches) { + calls.push([ + obj, + patches + ]); + } + Type[canSymbol.for('can.onInstancePatches')](handler); + var instance = new Type({ + first: 'Justin', + last: 'Meyer' + }); + canReflect.setKeyValue(instance, 'first', 'Payal'); + canReflect.setKeyValue(instance, 'last', 'Shah'); + canReflect.setKeyValue(instance, 'middle', 'p'); + Type[canSymbol.for('can.offInstancePatches')](handler); + canReflect.setKeyValue(instance, 'first', 'Ramiya'); + canReflect.setKeyValue(instance, 'last', 'Mayer'); + canReflect.setKeyValue(instance, 'middle', 'P'); + QUnit.deepEqual(calls, [ + [ + instance, + [{ + type: 'set', + key: 'first', + value: 'Payal' + }] + ], + [ + instance, + [{ + type: 'set', + key: 'last', + value: 'Shah' + }] + ], + [ + instance, + [{ + type: 'set', + key: 'middle', + value: 'p' + }] + ] + ]); + }); + }; +}); +/*can-reflect-tests@0.2.1#observables/map-like/type/type*/ +define('can-reflect-tests@0.2.1#observables/map-like/type/type', [ + 'require', + 'exports', + 'module', + './define-instance-key', + './define-instance-key-enumerable', + './on-instance-bound-change', + './on-instance-patches' +], function (require, exports, module) { + var defineInstanceKey = require('./define-instance-key'); + var defineInstanceKeyEnumerable = require('./define-instance-key-enumerable'); + var onInstanceBoundChange = require('./on-instance-bound-change'); + var onInstanceBatches = require('./on-instance-patches'); + module.exports = function (name, makeType) { + defineInstanceKey(name, makeType); + defineInstanceKeyEnumerable(name, makeType); + onInstanceBoundChange(name, makeType); + onInstanceBatches(name, makeType); + }; +}); +/*can-reflect-tests@0.2.1#observables/list-like/type/on-instance-patches*/ +define('can-reflect-tests@0.2.1#observables/list-like/type/on-instance-patches', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-symbol', + 'can-reflect' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + module.exports = function (name, makeType) { + QUnit.test(name + ' canRelect.onInstancePatches with splice', function () { + var Type = makeType(); + var calls = []; + function handler(obj, patches) { + calls.push([ + obj, + patches + ]); + } + Type[canSymbol.for('can.onInstancePatches')](handler); + var list = new Type([ + 1, + 2 + ]); + list.splice(2, 0, 3); + Type[canSymbol.for('can.offInstancePatches')](handler); + list.splice(3, 0, 4); + QUnit.deepEqual(calls, [[ + list, + [{ + type: 'splice', + index: 2, + deleteCount: 0, + insert: [3] + }] + ]]); + }); + }; +}); +/*can-define@2.7.1#test/test-type-events*/ +define('can-define@2.7.1#test/test-type-events', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-define/list/list', + 'can-define/map/map', + 'can-reflect-tests/observables/map-like/type/type', + 'can-reflect-tests/observables/map-like/type/define-instance-key', + 'can-reflect-tests/observables/map-like/type/on-instance-bound-change', + 'can-reflect-tests/observables/map-like/type/on-instance-patches', + 'can-reflect-tests/observables/list-like/type/on-instance-patches' +], function (require, exports, module) { + 'use strict'; + var QUnit = require('steal-qunit'); + var DefineList = require('can-define/list/list'); + var DefineMap = require('can-define/map/map'); + QUnit.module('can-define Type events'); + require('can-reflect-tests/observables/map-like/type/type')('DefineMap', function () { + return DefineMap.extend({ seal: false }, {}); + }); + require('can-reflect-tests/observables/map-like/type/define-instance-key')('DefineList', function () { + return DefineList.extend(); + }); + require('can-reflect-tests/observables/map-like/type/on-instance-bound-change')('DefineList', function () { + return DefineList.extend(); + }); + require('can-reflect-tests/observables/map-like/type/on-instance-patches')('DefineList', function () { + return DefineList.extend(); + }); + require('can-reflect-tests/observables/list-like/type/on-instance-patches')('DefineList', function () { + return DefineList.extend(); + }); +}); +/*can-define@2.7.1#test/test-value-resolve*/ +define('can-define@2.7.1#test/test-value-resolve', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-define/list/list', + 'can-define/map/map', + 'can-reflect', + 'can-queues', + 'can-observation-recorder' +], function (require, exports, module) { + 'use strict'; + var QUnit = require('steal-qunit'); + require('can-define/list/list'); + var DefineMap = require('can-define/map/map'); + var canReflect = require('can-reflect'); + var queues = require('can-queues'); + var ObservationRecorder = require('can-observation-recorder'); + QUnit.module('can-define value with resolve'); + QUnit.test('counter', function () { + var Person = DefineMap.extend('Person', { + name: 'string', + nameChangeCount: { + value: function (prop) { + var count = 0; + prop.resolve(count); + prop.listenTo('name', function () { + prop.resolve(++count); + }); + } + } + }); + var me = new Person(); + QUnit.equal(me.nameChangeCount, 0, 'unbound value'); + me.name = 'first'; + QUnit.equal(me.nameChangeCount, 0, 'unbound value'); + me.on('nameChangeCount', function (ev, newVal, oldVal) { + QUnit.equal(newVal, 1, 'updated count'); + QUnit.equal(oldVal, 0, 'updated count from old value'); + }); + me.name = 'second'; + QUnit.equal(me.nameChangeCount, 1, 'bound value'); + }); + QUnit.test('fullName getter the hard way', 3, function () { + var Person = DefineMap.extend('Person', { + first: 'string', + last: 'string', + fullName: { + value: function (prop) { + var first = this.first, last = this.last; + prop.resolve(first + ' ' + last); + prop.listenTo('first', function (ev, newFirst) { + first = newFirst; + prop.resolve(first + ' ' + last); + }); + prop.listenTo('last', function (ev, newLast) { + last = newLast; + prop.resolve(first + ' ' + last); + }); + } + } + }); + var me = new Person({ + first: 'Justin', + last: 'Meyer' + }); + QUnit.equal(me.fullName, 'Justin Meyer', 'unbound value'); + var handler = function (ev, newVal, oldVal) { + QUnit.equal(newVal, 'Ramiya Meyer', 'event newVal'); + QUnit.equal(oldVal, 'Justin Meyer', 'event oldVal'); + }; + me.on('fullName', handler); + me.first = 'Ramiya'; + me.off('fullName', handler); + me.last = 'Shah'; + }); + QUnit.test('list length', function () { + var VM = DefineMap.extend('VM', { + tasks: [], + tasksLength: { + value: function (prop) { + var tasks; + function checkAndResolve() { + if (tasks) { + prop.resolve(tasks.length); + } else { + prop.resolve(0); + } + } + function updateTask(ev, newTask, oldTask) { + if (oldTask) { + prop.stopListening(oldTask); + } + tasks = newTask; + if (newTask) { + prop.listenTo(newTask, 'length', function (ev, newVal) { + prop.resolve(newVal); + }); + } + checkAndResolve(); + } + prop.listenTo('tasks', updateTask); + updateTask(null, this.tasks, null); + } + } + }); + var vm = new VM({ tasks: null }); + QUnit.equal(vm.tasksLength, 0, 'empty tasks, unbound'); + vm.tasks = [ + 'chore 1', + 'chore 2' + ]; + QUnit.equal(vm.tasksLength, 2, 'tasks, unbound'); + var lengths = []; + vm.on('tasksLength', function (ev, newLength) { + lengths.push(newLength); + }); + QUnit.equal(vm.tasksLength, 2, '2 tasks, bound'); + vm.tasks.push('chore 3'); + var originalTasks = vm.tasks; + QUnit.equal(vm.tasksLength, 3, '3 tasks, bound, after push to source'); + vm.tasks = ['one chore']; + QUnit.equal(vm.tasksLength, 1, '1 tasks, bound, after replace array'); + QUnit.notOk(canReflect.isBound(originalTasks), 'not bound on original'); + QUnit.deepEqual(lengths, [ + 3, + 1 + ], 'length changes are right'); + }); + QUnit.test('batches produce one result', 2, function () { + var Person = DefineMap.extend('Person', { + first: 'string', + last: 'string', + fullName: { + value: function (prop) { + var first = this.first, last = this.last; + prop.resolve(first + ' ' + last); + prop.listenTo('first', function (ev, newFirst) { + first = newFirst; + prop.resolve(first + ' ' + last); + }); + prop.listenTo('last', function (ev, newLast) { + last = newLast; + prop.resolve(first + ' ' + last); + }); + } + } + }); + var me = new Person({ + first: 'Justin', + last: 'Meyer' + }); + var handler = function (ev, newVal, oldVal) { + QUnit.equal(newVal, 'Ramiya Shah', 'event newVal'); + QUnit.equal(oldVal, 'Justin Meyer', 'event oldVal'); + }; + me.on('fullName', handler); + queues.batch.start(); + me.first = 'Ramiya'; + me.last = 'Shah'; + queues.batch.stop(); + }); + QUnit.test('location vm', function () { + var Locator = DefineMap.extend('Locator', { + state: 'string', + setCity: function (city) { + this.dispatch('citySet', city); + }, + city: { + value: function (prop) { + prop.listenTo('citySet', function (ev, city) { + prop.resolve(city); + }); + prop.listenTo('state', function () { + prop.resolve(null); + }); + } + } + }); + var locator = new Locator({ state: 'IL' }); + locator.on('city', function () { + }); + locator.setCity('Chicago'); + locator.state = 'CA'; + QUnit.equal(locator.city, null, 'changing the state sets the city'); + }); + QUnit.test('location vm with setter', function () { + var Locator = DefineMap.extend('Locator', { + state: 'string', + city: { + value: function (prop) { + prop.listenTo(prop.lastSet, prop.resolve); + prop.listenTo('state', function () { + prop.resolve(null); + }); + prop.resolve(prop.lastSet.get()); + } + } + }); + var locator = new Locator({ + state: 'IL', + city: 'Chicago' + }); + QUnit.equal(locator.city, 'Chicago', 'init to Chicago'); + locator.on('city', function () { + }); + locator.state = 'CA'; + QUnit.equal(locator.city, null, 'changing the state sets the city'); + locator.city = 'San Jose'; + QUnit.equal(locator.city, 'San Jose', 'changing the state sets the city'); + }); + QUnit.test('events should not be fired when resolve is not called', function () { + var Numbers = DefineMap.extend('Numbers', { + oddNumber: { + value: function (prop) { + prop.resolve(5); + prop.listenTo(prop.lastSet, function (newVal) { + if (newVal % 2) { + prop.resolve(newVal); + } + }); + } + } + }); + var nums = new Numbers({}); + QUnit.equal(nums.oddNumber, 5, 'initial value is 5'); + nums.on('oddNumber', function (ev, newVal) { + QUnit.equal(newVal % 2, 1, 'event dispatched for ' + newVal); + }); + nums.oddNumber = 7; + nums.oddNumber = 8; + }); + QUnit.test('reading properties does not leak out', function () { + var Type = DefineMap.extend({ + prop: { + value: function (prop) { + prop.resolve(this.value); + } + }, + value: { default: 'hi' } + }); + var t = new Type(); + ObservationRecorder.start(); + t.on('prop', function () { + }); + var records = ObservationRecorder.stop(); + QUnit.equal(records.keyDependencies.size, 0, 'there are no key dependencies'); + }); +}); +/*can-define@2.7.1#test/test*/ +define('can-define@2.7.1#test/test', [ + 'require', + 'exports', + 'module', + './test-define-only', + '../list/list-test', + '../map/map-test', + './test-list-and-map', + './test-type-events', + './test-value-resolve' +], function (require, exports, module) { + require('./test-define-only'); + require('../list/list-test'); + require('../map/map-test'); + require('./test-list-and-map'); + require('./test-type-events'); + require('./test-value-resolve'); +}); +/*can-stache-bindings@4.6.4#test/helpers*/ +define('can-stache-bindings@4.6.4#test/helpers', [ + 'require', + 'exports', + 'module', + 'can-globals', + 'can-dom-events', + 'can-dom-mutate', + 'can-dom-mutate/node', + 'can-dom-data-state', + 'can-vdom/make-document/make-document' +], function (require, exports, module) { + (function (global, require, exports, module) { + var globals = require('can-globals'); + var domEvents = require('can-dom-events'); + var domMutate = require('can-dom-mutate'); + var domMutateNode = require('can-dom-mutate/node'); + var domData = require('can-dom-data-state'); + var makeDocument = require('can-vdom/make-document/make-document'); + var helpers = { + makeQUnitModule: function (name, doc, enableMO) { + QUnit.module(name, { + setup: function () { + globals.setKeyValue('document', doc); + if (!enableMO) { + globals.setKeyValue('MutationObserver', null); + } + if (doc === document) { + this.fixture = document.getElementById('qunit-fixture'); + } else { + this.fixture = doc.createElement('qunit-fixture'); + doc.body.appendChild(this.fixture); + } + }, + teardown: function () { + if (doc !== document) { + doc.body.removeChild(this.fixture); + } + stop(); + helpers.afterMutation(function () { + globals.deleteKeyValue('document'); + globals.deleteKeyValue('MutationObserver'); + var fixture = document.getElementById('qunit-fixture'); + while (fixture && fixture.hasChildNodes()) { + domData.delete.call(fixture.lastChild); + fixture.removeChild(fixture.lastChild); + } + start(); + }); + } + }); + }, + afterMutation: function (cb) { + var doc = globals.getKeyValue('document'); + var div = doc.createElement('div'); + var undo = domMutate.onNodeInsertion(div, function () { + undo(); + doc.body.removeChild(div); + setTimeout(cb, 5); + }); + setTimeout(function () { + domMutateNode.appendChild.call(doc.body, div); + }, 10); + }, + makeTests: function (name, makeTest) { + helpers.makeQUnitModule(name + ' - dom', document, true); + makeTest(name + ' - dom', document, true, QUnit.test); + var doc = makeDocument(); + helpers.makeQUnitModule(name + ' - vdom', doc, false); + makeTest(name + ' - vdom', doc, false, function () { + }); + }, + interceptDomEvents: function (addFn, removeFn) { + var realAddEventListener = domEvents.addEventListener; + var realRemoveEventListener = domEvents.removeEventListener; + domEvents.addEventListener = function (eventName) { + addFn.call(this, arguments); + return realAddEventListener.apply(this, arguments); + }; + domEvents.removeEventListener = function (eventName) { + removeFn.call(this, arguments); + return realRemoveEventListener.apply(this, arguments); + }; + return function undo() { + domEvents.addEventListener = realAddEventListener; + domEvents.removeEventListener = realRemoveEventListener; + }; + } + }; + module.exports = helpers; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-stache-bindings@4.6.4#test/mock-component-simple-map*/ +define('can-stache-bindings@4.6.4#test/mock-component-simple-map', [ + 'require', + 'exports', + 'module', + 'can-stache-bindings', + 'can-simple-map', + 'can-view-callbacks', + 'can-view-nodelist', + 'can-symbol', + 'can-dom-data-state', + 'can-dom-mutate/node' +], function (require, exports, module) { + var stacheBindings = require('can-stache-bindings'); + var CanSimpleMap = require('can-simple-map'); + var viewCallbacks = require('can-view-callbacks'); + var nodeLists = require('can-view-nodelist'); + var canSymbol = require('can-symbol'); + var domData = require('can-dom-data-state'); + var domMutateNode = require('can-dom-mutate/node'); + var MockComponent; + module.exports = MockComponent = { + extend: function (proto) { + viewCallbacks.tag(proto.tag, function (el, componentTagData) { + var viewModel; + var teardownBindings = stacheBindings.behaviors.viewModel(el, componentTagData, function (initialViewModelData) { + if (typeof proto.viewModel === 'function') { + return viewModel = new proto.viewModel(initialViewModelData); + } else if (proto.viewModel instanceof CanSimpleMap) { + proto.viewModel.set(initialViewModelData); + return viewModel = proto.viewModel; + } else { + var VM = CanSimpleMap.extend(proto.viewModel); + return viewModel = new VM(initialViewModelData); + } + }, {}); + el[canSymbol.for('can.viewModel')] = viewModel; + el.viewModel = viewModel; + domData.set.call(el, 'preventDataBindings', true); + if (proto.template) { + var shadowScope = componentTagData.scope.add(viewModel); + domData.set.call(el, 'shadowScope', shadowScope); + var nodeList = nodeLists.register([], function () { + teardownBindings(); + }, componentTagData.parentNodeList || true, false); + var frag = proto.template(shadowScope, componentTagData.options, nodeList); + domMutateNode.appendChild.call(el, frag); + } + }); + } + }; +}); +/*can-stache-bindings@4.6.4#test/colon/basics-test*/ +define('can-stache-bindings@4.6.4#test/colon/basics-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + '../helpers', + 'can-stache-bindings', + 'can-dom-events', + 'can-stache', + 'can-simple-map', + '../mock-component-simple-map', + 'can-attribute-encoder', + 'can-test-helpers' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var testHelpers = require('../helpers'); + var stacheBindings = require('can-stache-bindings'); + var domEvents = require('can-dom-events'); + var stache = require('can-stache'); + var SimpleMap = require('can-simple-map'); + var MockComponent = require('../mock-component-simple-map'); + var encoder = require('can-attribute-encoder'); + var canTestHelpers = require('can-test-helpers'); + testHelpers.makeTests('can-stache-bindings - colon - basics', function (name, doc, enableMO) { + test('basics', 5, function () { + var viewModel = new SimpleMap({ + toChild: 'toChild', + toParent: 'toParent', + twoWay: 'twoWay' + }); + MockComponent.extend({ + tag: 'basic-colon', + viewModel: viewModel + }); + var template = stache(''); + var MySimpleMap = SimpleMap.extend({ + methodD: function () { + QUnit.ok(true, 'on:vmevent bindings work'); + } + }); + var parent = new MySimpleMap({ + valueA: 'A', + valueB: 'B', + valueC: 'C' + }); + template(parent); + QUnit.deepEqual(parent.get(), { + valueA: 'A', + valueB: 'toParent', + valueC: 'C' + }, 'initial scope values correct'); + QUnit.deepEqual(viewModel.get(), { + toChild: 'A', + toParent: 'toParent', + twoWay: 'C' + }, 'initial VM values correct'); + parent.set({ + valueA: 'a', + valueB: 'b', + valueC: 'c' + }); + QUnit.deepEqual(viewModel.get(), { + toChild: 'a', + toParent: 'toParent', + twoWay: 'c' + }, 'scope set VM values correct'); + viewModel.set({ + toChild: 'to-child', + toParent: 'to-parent', + twoWay: 'two-way' + }); + QUnit.deepEqual(parent.get(), { + valueA: 'a', + valueB: 'to-parent', + valueC: 'two-way' + }, 'vm set scope values correct'); + viewModel.dispatch({ type: 'vmevent' }); + }); + test('getBindingInfo', function () { + var info = stacheBindings.getBindingInfo({ + name: 'foo-ed:from', + value: 'bar' + }); + deepEqual(info, { + parent: 'scope', + child: 'viewModelOrAttribute', + childEvent: undefined, + parentToChild: true, + childToParent: false, + childName: 'foo-ed', + parentName: 'bar', + bindingAttributeName: 'foo-ed:from', + initializeValues: true, + syncChildWithParent: false + }, ':from'); + info = stacheBindings.getBindingInfo({ + name: 'foo-ed:bind', + value: 'bar' + }); + deepEqual(info, { + parent: 'scope', + child: 'viewModelOrAttribute', + childEvent: undefined, + parentToChild: true, + childToParent: true, + childName: 'foo-ed', + parentName: 'bar', + bindingAttributeName: 'foo-ed:bind', + initializeValues: true, + syncChildWithParent: true + }, ':bind'); + info = stacheBindings.getBindingInfo({ + name: 'foo-ed:to', + value: 'bar' + }); + deepEqual(info, { + parent: 'scope', + child: 'viewModelOrAttribute', + childEvent: undefined, + parentToChild: false, + childToParent: true, + childName: 'foo-ed', + parentName: 'bar', + bindingAttributeName: 'foo-ed:to', + initializeValues: true, + syncChildWithParent: false + }, ':to'); + info = stacheBindings.getBindingInfo({ + name: 'foo-ed:from', + value: 'bar' + }, null, null, null, true); + deepEqual(info, { + parent: 'scope', + child: 'viewModel', + childEvent: undefined, + parentToChild: true, + childToParent: false, + childName: 'foo-ed', + parentName: 'bar', + bindingAttributeName: 'foo-ed:from', + initializeValues: true, + syncChildWithParent: false + }, ':from, favorViewModel=true'); + info = stacheBindings.getBindingInfo({ + name: 'foo-ed:bind', + value: 'bar' + }, null, null, null, true); + deepEqual(info, { + parent: 'scope', + child: 'viewModel', + childEvent: undefined, + parentToChild: true, + childToParent: true, + childName: 'foo-ed', + parentName: 'bar', + bindingAttributeName: 'foo-ed:bind', + initializeValues: true, + syncChildWithParent: true + }, ':bind, favorViewModel=true'); + info = stacheBindings.getBindingInfo({ + name: 'foo-ed:to', + value: 'bar' + }, null, null, null, true); + deepEqual(info, { + parent: 'scope', + child: 'viewModel', + childEvent: undefined, + parentToChild: false, + childToParent: true, + childName: 'foo-ed', + parentName: 'bar', + bindingAttributeName: 'foo-ed:to', + initializeValues: true, + syncChildWithParent: false + }, ':to, favorViewModel=true'); + }); + test('getBindingInfo for vm:', function () { + var info = stacheBindings.getBindingInfo({ + name: 'vm:foo-ed:from', + value: 'bar' + }); + deepEqual(info, { + parent: 'scope', + child: 'viewModel', + childEvent: undefined, + parentToChild: true, + childToParent: false, + childName: 'foo-ed', + parentName: 'bar', + bindingAttributeName: 'vm:foo-ed:from', + initializeValues: true, + syncChildWithParent: false + }, ':from'); + info = stacheBindings.getBindingInfo({ + name: 'vm:foo-ed:bind', + value: 'bar' + }); + deepEqual(info, { + parent: 'scope', + child: 'viewModel', + childEvent: undefined, + parentToChild: true, + childToParent: true, + childName: 'foo-ed', + parentName: 'bar', + bindingAttributeName: 'vm:foo-ed:bind', + initializeValues: true, + syncChildWithParent: true + }, ':bind'); + info = stacheBindings.getBindingInfo({ + name: 'vm:foo-ed:to', + value: 'bar' + }); + deepEqual(info, { + parent: 'scope', + child: 'viewModel', + childEvent: undefined, + parentToChild: false, + childToParent: true, + childName: 'foo-ed', + parentName: 'bar', + bindingAttributeName: 'vm:foo-ed:to', + initializeValues: true, + syncChildWithParent: false + }, ':to'); + info = stacheBindings.getBindingInfo({ + name: 'vm:foo-ed:from', + value: 'bar' + }, null, null, null, true); + deepEqual(info, { + parent: 'scope', + child: 'viewModel', + childEvent: undefined, + parentToChild: true, + childToParent: false, + childName: 'foo-ed', + parentName: 'bar', + bindingAttributeName: 'vm:foo-ed:from', + initializeValues: true, + syncChildWithParent: false + }, ':from, favorViewModel=true'); + info = stacheBindings.getBindingInfo({ + name: 'vm:foo-ed:bind', + value: 'bar' + }, null, null, null, true); + deepEqual(info, { + parent: 'scope', + child: 'viewModel', + childEvent: undefined, + parentToChild: true, + childToParent: true, + childName: 'foo-ed', + parentName: 'bar', + bindingAttributeName: 'vm:foo-ed:bind', + initializeValues: true, + syncChildWithParent: true + }, ':bind, favorViewModel=true'); + info = stacheBindings.getBindingInfo({ + name: 'vm:foo-ed:to', + value: 'bar' + }, null, null, null, true); + deepEqual(info, { + parent: 'scope', + child: 'viewModel', + childEvent: undefined, + parentToChild: false, + childToParent: true, + childName: 'foo-ed', + parentName: 'bar', + bindingAttributeName: 'vm:foo-ed:to', + initializeValues: true, + syncChildWithParent: false + }, ':to, favorViewModel=true'); + }); + test('getBindingInfo for el:', function () { + var info = stacheBindings.getBindingInfo({ + name: 'el:foo-ed:from', + value: 'bar' + }); + deepEqual(info, { + parent: 'scope', + child: 'attribute', + childEvent: undefined, + parentToChild: true, + childToParent: false, + childName: 'foo-ed', + parentName: 'bar', + bindingAttributeName: 'el:foo-ed:from', + initializeValues: true, + syncChildWithParent: false + }, ':from'); + info = stacheBindings.getBindingInfo({ + name: 'el:foo-ed:bind', + value: 'bar' + }); + deepEqual(info, { + parent: 'scope', + child: 'attribute', + childEvent: undefined, + parentToChild: true, + childToParent: true, + childName: 'foo-ed', + parentName: 'bar', + bindingAttributeName: 'el:foo-ed:bind', + initializeValues: true, + syncChildWithParent: true + }, ':bind'); + info = stacheBindings.getBindingInfo({ + name: 'el:foo-ed:to', + value: 'bar' + }); + deepEqual(info, { + parent: 'scope', + child: 'attribute', + childEvent: undefined, + parentToChild: false, + childToParent: true, + childName: 'foo-ed', + parentName: 'bar', + bindingAttributeName: 'el:foo-ed:to', + initializeValues: true, + syncChildWithParent: false + }, ':to'); + info = stacheBindings.getBindingInfo({ + name: 'el:foo-ed:from', + value: 'bar' + }, null, null, null, true); + deepEqual(info, { + parent: 'scope', + child: 'attribute', + childEvent: undefined, + parentToChild: true, + childToParent: false, + childName: 'foo-ed', + parentName: 'bar', + bindingAttributeName: 'el:foo-ed:from', + initializeValues: true, + syncChildWithParent: false + }, ':from, favorViewModel=true'); + info = stacheBindings.getBindingInfo({ + name: 'el:foo-ed:bind', + value: 'bar' + }, null, null, null, true); + deepEqual(info, { + parent: 'scope', + child: 'attribute', + childEvent: undefined, + parentToChild: true, + childToParent: true, + childName: 'foo-ed', + parentName: 'bar', + bindingAttributeName: 'el:foo-ed:bind', + initializeValues: true, + syncChildWithParent: true + }, ':bind, favorViewModel=true'); + info = stacheBindings.getBindingInfo({ + name: 'el:foo-ed:to', + value: 'bar' + }, null, null, null, true); + deepEqual(info, { + parent: 'scope', + child: 'attribute', + childEvent: undefined, + parentToChild: false, + childToParent: true, + childName: 'foo-ed', + parentName: 'bar', + bindingAttributeName: 'el:foo-ed:to', + initializeValues: true, + syncChildWithParent: false + }, ':to, favorViewModel=true'); + }); + QUnit.test('getBindingInfo works for value:to:on:click (#269)', function () { + var info = stacheBindings.getBindingInfo({ + name: 'value:to:on:click', + value: 'bar' + }); + deepEqual(info, { + parent: 'scope', + child: 'viewModelOrAttribute', + childEvent: 'click', + parentToChild: false, + childToParent: true, + childName: 'value', + parentName: 'bar', + bindingAttributeName: 'value:to:on:click', + initializeValues: false, + syncChildWithParent: false + }, 'new vm binding'); + }); + QUnit.test('decode values with To (#504)', function () { + var name = encoder.encode('goToHome:to'); + var info = stacheBindings.getBindingInfo({ + name: name, + value: 'bar' + }); + deepEqual(info, { + parent: 'scope', + child: 'viewModelOrAttribute', + childEvent: undefined, + parentToChild: false, + childToParent: true, + childName: 'goToHome', + parentName: 'bar', + bindingAttributeName: 'goToHome:to', + initializeValues: true, + syncChildWithParent: false + }, 'to parent binding'); + }); + canTestHelpers.dev.devOnlyTest('warning when binding to non-existing value (#136) (#119)', function () { + var teardown = canTestHelpers.dev.willWarn('This element does not have a viewModel. (Attempting to bind `target:vm:bind="source.bar"`)'); + var template = stache('
    '); + var map = new SimpleMap({ source: new SimpleMap({ foo: 'foo' }) }); + template(map); + QUnit.equal(teardown(), 1, 'warning shown'); + }); + QUnit.test('parent stache is able to teardown child bindings (#278)', function () { + var map = new SimpleMap({ value: 'VALUE' }); + var template = stache('
    {{#if value}}{{/if}}
    '); + var frag = template(map), input = frag.firstChild.getElementsByTagName('input')[0]; + this.fixture.appendChild(frag); + QUnit.equal(input.value, 'VALUE', 'value set initially'); + map.set('value', ''); + QUnit.equal(input.value, 'VALUE', 'value should not have been updated'); + }); + QUnit.test('bindings still work for moved elements (#460)', function (assert) { + var done = assert.async(); + var map = new SimpleMap({ value: 'first' }); + var template = stache(''); + var frag = template(map); + var input = frag.firstChild; + this.fixture.appendChild(frag); + var div = doc.createElement('div'); + this.fixture.appendChild(div); + div.appendChild(input); + testHelpers.afterMutation(function () { + map.set('value', 'second'); + QUnit.equal(input.value, 'second', 'value should have been updated'); + input.value = 'third'; + domEvents.dispatch(input, 'change'); + QUnit.equal(map.get('value'), 'third', 'map should have been updated'); + done(); + }); + }); + }); +}); +/*can-stache-bindings@4.6.4#test/colon/element-test*/ +define('can-stache-bindings@4.6.4#test/colon/element-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + '../helpers', + 'can-stache', + 'can-stache-bindings', + 'can-simple-map', + 'can-define/list/list', + '../mock-component-simple-map', + 'can-view-model', + 'can-simple-observable', + 'can-symbol', + 'can-reflect', + 'can-dom-mutate', + 'can-dom-mutate/node', + 'can-dom-events', + 'can-define/map/map' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var testHelpers = require('../helpers'); + var stache = require('can-stache'); + require('can-stache-bindings'); + var SimpleMap = require('can-simple-map'); + var DefineList = require('can-define/list/list'); + var MockComponent = require('../mock-component-simple-map'); + var canViewModel = require('can-view-model'); + var SimpleObservable = require('can-simple-observable'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + var domMutate = require('can-dom-mutate'); + var domMutateNode = require('can-dom-mutate/node'); + var domEvents = require('can-dom-events'); + var DefineMap = require('can-define/map/map'); + testHelpers.makeTests('can-stache-bindings - colon - element', function (name, doc, enableMO, testIfRealDocument) { + QUnit.test(' value:bind input text', function () { + var template = stache(''); + var map = new SimpleMap(); + var frag = template(map); + var ta = this.fixture; + ta.appendChild(frag); + var input = ta.getElementsByTagName('input')[0]; + equal(input.value, '', 'input value set correctly if key does not exist in map'); + map.set('age', '30'); + equal(input.value, '30', 'input value set correctly'); + map.set('age', '31'); + equal(input.value, '31', 'input value update correctly'); + input.value = '32'; + domEvents.dispatch(input, 'change'); + equal(map.get('age'), '32', 'updated from input'); + }); + QUnit.test(' el:prop:to/:from/:bind work (#280)', function () { + var template = stache('' + '' + ''); + var scope = new SimpleMap({ + scope1: 'scope1', + scope2: 'scope2', + scope3: 'scope3' + }); + var frag = template(scope); + var ta = this.fixture; + ta.appendChild(frag); + var inputTo = ta.getElementsByTagName('input')[0]; + var inputFrom = ta.getElementsByTagName('input')[1]; + var inputBind = ta.getElementsByTagName('input')[2]; + equal(scope.attr('scope1'), '1', 'el:value:to - scope value set from attribute'); + inputTo.value = '4'; + domEvents.dispatch(inputTo, 'change'); + equal(scope.attr('scope1'), '4', 'el:value:to - scope updated when attribute changed'); + scope.attr('scope1', 'scope4'); + equal(inputTo.value, '4', 'el:value:to - attribute not updated when scope changed'); + equal(inputFrom.value, 'scope2', 'el:value:from - attribute set from scope'); + inputFrom.value = 'scope5'; + domEvents.dispatch(inputFrom, 'change'); + equal(scope.attr('scope2'), 'scope2', 'el:value:from - scope not updated when attribute changed'); + scope.attr('scope2', 'scope6'); + equal(inputFrom.value, 'scope6', 'el:value:from - attribute updated when scope changed'); + equal(inputBind.value, 'scope3', 'el:value:bind - attribute set from scope prop (parent -> child wins)'); + inputBind.value = 'scope6'; + domEvents.dispatch(inputBind, 'change'); + equal(scope.attr('scope3'), 'scope6', 'el:value:bind - scope updated when attribute changed'); + scope.attr('scope3', 'scope7'); + equal(inputBind.value, 'scope7', 'el:value:bind - attribute updated when scope changed'); + }); + if (System.env !== 'canjs-test') { + test(' dynamic attribute bindings (#2016)', function (assert) { + var done = assert.async(); + var template = stache(''); + var map = new SimpleMap({ + propName: 'first', + first: 'Justin', + last: 'Meyer' + }); + var frag = template(map); + var ta = this.fixture; + ta.appendChild(frag); + var input = ta.getElementsByTagName('input')[0]; + testHelpers.afterMutation(function () { + equal(input.value, 'Justin', 'input value set correctly if key does not exist in map'); + map.set('propName', 'last'); + testHelpers.afterMutation(function () { + equal(input.value, 'Meyer', 'input value set correctly if key does not exist in map'); + input.value = 'Lueke'; + domEvents.dispatch(input, 'change'); + testHelpers.afterMutation(function () { + equal(map.get('last'), 'Lueke', 'updated from input'); + done(); + }); + }); + }); + }); + } + test('value:bind compute rejects new value (#887)', function () { + var template = stache(''); + var compute = new SimpleObservable(30); + canReflect.assignSymbols(compute, { + 'can.setValue': function (newVal) { + if (isNaN(+newVal)) { + } else { + this.set(+newVal); + } + } + }); + var frag = template({ age: compute }); + var ta = this.fixture; + ta.appendChild(frag); + var input = ta.getElementsByTagName('input')[0]; + input.value = '30f'; + domEvents.dispatch(input, 'change'); + equal(compute.get(), 30, 'Still the old value'); + equal(input.value, '30', 'Text input has also not changed'); + }); + test('value:from works with camelCase and kebab-case properties', function () { + var template = stache('' + ''); + var map = new SimpleMap({}); + var frag = template(map); + var ta = this.fixture; + ta.appendChild(frag); + var camelPropInput = ta.getElementsByTagName('input')[0]; + var kebabPropInput = ta.getElementsByTagName('input')[1]; + equal(camelPropInput.value, '', 'input bound to camelCase prop value set correctly if camelCase key does not exist in map'); + equal(kebabPropInput.value, '', 'input bound to kebab-case prop value set correctly if kebab-case key does not exist in map'); + map.attr('theProp', '30'); + equal(camelPropInput.value, '30', 'input bound to camelCase prop value set correctly when camelCase prop changes'); + equal(kebabPropInput.value, '', 'input bound to kebab-case prop value not updated when camelCase prop changes'); + map.attr('theProp', '31'); + equal(camelPropInput.value, '31', 'input bound to camelCase prop value updated correctly when camelCase prop changes'); + ok(!kebabPropInput.value, 'input bound to kebab-case prop value not updated when camelCase prop changes'); + camelPropInput.value = '32'; + domEvents.dispatch(camelPropInput, 'change'); + equal(map.attr('theProp'), '31', 'camelCase prop NOT updated when input bound to camelCase prop changes'); + ok(!map.attr('the-prop'), 'kebabCase prop NOT updated when input bound to camelCase prop changes'); + map.attr('the-prop', '33'); + equal(kebabPropInput.value, '33', 'input bound to kebab-case prop value set correctly when kebab-case prop changes'); + equal(camelPropInput.value, '32', 'input bound to camelCase prop value not updated when kebab-case prop changes'); + map.attr('the-prop', '34'); + equal(kebabPropInput.value, '34', 'input bound to kebab-case prop value updated correctly when kebab-case prop changes'); + equal(camelPropInput.value, '32', 'input bound to camelCase prop value not updated when kebab-case prop changes'); + kebabPropInput.value = '35'; + domEvents.dispatch(kebabPropInput, 'change'); + equal(map.attr('the-prop'), '34', 'kebab-case prop NOT updated from input bound to kebab-case prop'); + equal(map.attr('theProp'), '31', 'camelCase prop NOT updated from input bound to kebab-case prop'); + }); + test('value:to works with camelCase and kebab-case properties', function () { + var template = stache('' + ''); + var map = new SimpleMap({}); + var frag = template(map); + var ta = this.fixture; + ta.appendChild(frag); + var camelPropInput = ta.getElementsByTagName('input')[0]; + var kebabPropInput = ta.getElementsByTagName('input')[1]; + camelPropInput.value = '32'; + domEvents.dispatch(camelPropInput, 'change'); + equal(map.attr('theProp'), '32', 'camelCaseProp updated from input bound to camelCase Prop'); + ok(!map.attr('the-prop'), 'kebabCaseProp NOT updated from input bound to camelCase Prop'); + map.attr('theProp', '30'); + equal(camelPropInput.value, '32', 'input bound to camelCase Prop value NOT updated when camelCase prop changes'); + ok(!kebabPropInput.value, 'input bound to kebabCase Prop value NOT updated when camelCase prop changes'); + kebabPropInput.value = '33'; + domEvents.dispatch(kebabPropInput, 'change'); + equal(map.attr('the-prop'), '33', 'kebabCaseProp updated from input bound to kebabCase Prop'); + equal(map.attr('theProp'), '30', 'camelCaseProp NOT updated from input bound to camelCase Prop'); + map.attr('theProp', '34'); + equal(kebabPropInput.value, '33', 'input bound to kebabCase Prop value NOT updated when kebabCase prop changes'); + equal(camelPropInput.value, '32', 'input bound to camelCase Prop value NOT updated when kebabCase prop changes'); + }); + test('value:bind works with camelCase and kebab-case properties', function () { + var template = stache('' + ''); + var map = new SimpleMap({}); + var frag = template(map); + var ta = this.fixture; + ta.appendChild(frag); + var camelPropInput = ta.getElementsByTagName('input')[0]; + var kebabPropInput = ta.getElementsByTagName('input')[1]; + camelPropInput.value = '32'; + domEvents.dispatch(camelPropInput, 'change'); + equal(map.attr('theProp'), '32', 'camelCaseProp updated from input bound to camelCase Prop'); + ok(!map.attr('the-prop'), 'kebabCaseProp NOT updated from input bound to camelCase Prop'); + map.attr('theProp', '30'); + equal(camelPropInput.value, '30', 'input bound to camelCase Prop value updated when camelCase prop changes'); + ok(!kebabPropInput.value, 'input bound to kebabCase Prop value NOT updated when camelCase prop changes'); + kebabPropInput.value = '33'; + domEvents.dispatch(kebabPropInput, 'change'); + equal(map.attr('the-prop'), '33', 'kebabCaseProp updated from input bound to kebabCase Prop'); + equal(map.attr('theProp'), '30', 'camelCaseProp NOT updated from input bound to camelCase Prop'); + map.attr('theProp', '34'); + equal(kebabPropInput.value, '33', 'input bound to kebabCase Prop value NOT updated when kebabCase prop changes'); + equal(camelPropInput.value, '34', 'input bound to camelCase Prop value updated when kebabCase prop changes'); + }); + test('Bracket expression with dot and no explicit root and value:bind', function () { + var template; + var div = this.fixture; + template = stache(''); + var data = new SimpleMap(); + var dom = template(data); + div.appendChild(dom); + var input = div.getElementsByTagName('input')[0]; + equal(input.value, '', 'input value set correctly if key does not exist in map'); + data.set('two.hops', 'slide to the left'); + equal(input.value, 'slide to the left', 'input value set correctly'); + data.set('two.hops', 'slide to the right'); + equal(input.value, 'slide to the right', 'input value update correctly'); + input.value = 'REVERSE REVERSE'; + domEvents.dispatch(input, 'change'); + equal(data.get('two.hops'), 'REVERSE REVERSE', 'updated from input'); + }); + test('Bracket expression with colon and no explicit root and value:bind', function () { + var template; + var div = this.fixture; + template = stache(''); + var data = new SimpleMap(); + var dom = template(data); + div.appendChild(dom); + var input = div.getElementsByTagName('input')[0]; + equal(input.value, '', 'input value set correctly if key does not exist in map'); + data.set('two:hops', 'slide to the left'); + equal(input.value, 'slide to the left', 'input value set correctly'); + data.set('two:hops', 'slide to the right'); + equal(input.value, 'slide to the right', 'input value update correctly'); + input.value = 'REVERSE REVERSE'; + domEvents.dispatch(input, 'change'); + equal(data.get('two:hops'), 'REVERSE REVERSE', 'updated from input'); + }); + QUnit.test('el:prop:to/:from/:bind work (#280)', function () { + var template = stache('' + '' + ''); + var scope = new SimpleMap({ + scope1: 'scope1', + scope2: 'scope2', + scope3: 'scope3' + }); + var frag = template(scope); + var ta = this.fixture; + ta.appendChild(frag); + var inputTo = ta.getElementsByTagName('input')[0]; + var inputFrom = ta.getElementsByTagName('input')[1]; + var inputBind = ta.getElementsByTagName('input')[2]; + equal(scope.attr('scope1'), '1', 'el:value:to - scope value set from attribute'); + inputTo.value = '4'; + domEvents.dispatch(inputTo, 'change'); + equal(scope.attr('scope1'), '4', 'el:value:to - scope updated when attribute changed'); + scope.attr('scope1', 'scope4'); + equal(inputTo.value, '4', 'el:value:to - attribute not updated when scope changed'); + equal(inputFrom.value, 'scope2', 'el:value:from - attribute set from scope'); + inputFrom.value = 'scope5'; + domEvents.dispatch(inputFrom, 'change'); + equal(scope.attr('scope2'), 'scope2', 'el:value:from - scope not updated when attribute changed'); + scope.attr('scope2', 'scope6'); + equal(inputFrom.value, 'scope6', 'el:value:from - attribute updated when scope changed'); + equal(inputBind.value, 'scope3', 'el:value:bind - attribute set from scope prop (parent -> child wins)'); + inputBind.value = 'scope6'; + domEvents.dispatch(inputBind, 'change'); + equal(scope.attr('scope3'), 'scope6', 'el:value:bind - scope updated when attribute changed'); + scope.attr('scope3', 'scope7'); + equal(inputBind.value, 'scope7', 'el:value:bind - attribute updated when scope changed'); + }); + test(' two-way - DOM - input text (#1700)', function () { + var template = stache(''); + var map = new SimpleMap(); + var frag = template(map); + var ta = this.fixture; + ta.appendChild(frag); + var input = ta.getElementsByTagName('input')[0]; + equal(input.value, '', 'input value set correctly if key does not exist in map'); + map.attr('age', '30'); + stop(); + testHelpers.afterMutation(function () { + start(); + equal(input.value, '30', 'input value set correctly'); + map.attr('age', '31'); + stop(); + testHelpers.afterMutation(function () { + start(); + equal(input.value, '31', 'input value update correctly'); + input.value = '32'; + domEvents.dispatch(input, 'change'); + stop(); + testHelpers.afterMutation(function () { + start(); + equal(map.attr('age'), '32', 'updated from input'); + }); + }); + }); + }); + QUnit.test('errors subproperties of undefined properties (#298)', function () { + try { + stache('')(); + ok(true, 'renderer was made without error'); + } catch (e) { + ok(false, e.message); + } + }); + test('updates happen on two-way even when one binding is satisfied', function (assert) { + var done = assert.async(); + var template = stache(''); + var viewModel = new SimpleMap({ firstName: 'jeffrey' }); + canReflect.assignSymbols(viewModel, { + 'can.setKeyValue': function (key, val) { + if (val) { + this.set(key, val.toLowerCase()); + } + } + }); + var frag = template(viewModel); + domMutateNode.appendChild.call(this.fixture, frag); + var input = this.fixture.firstChild; + assert.equal(input.value, 'jeffrey', 'initial value should be "jeffrey"'); + input.value = 'JEFFREY'; + domEvents.dispatch(input, 'change'); + assert.equal(input.value, 'jeffrey', 'updated value should be "jeffrey"'); + testHelpers.afterMutation(function () { + done(); + }); + }); + QUnit.test('updates happen on changed two-way even when one binding is satisfied', function (assert) { + var done = assert.async(); + var template = stache(''); + var ViewModel = DefineMap.extend({ + firstName: { + set: function (newValue) { + if (newValue) { + return newValue.toLowerCase(); + } + } + }, + lastName: { + set: function (newValue) { + if (newValue) { + return newValue.toLowerCase(); + } + } + }, + bindValue: 'string' + }); + var viewModel = new ViewModel({ + firstName: 'Jeffrey', + lastName: 'King', + bindValue: 'firstName' + }); + var frag = template(viewModel); + domMutateNode.appendChild.call(this.fixture, frag); + var input = this.fixture.firstChild; + testHelpers.afterMutation(function () { + assert.equal(input.value, 'jeffrey'); + var undo = domMutate.onNodeAttributeChange(input, function () { + undo(); + assert.equal(input.value, 'king', 'should be king'); + setTimeout(function () { + input.value = 'KING'; + domEvents.dispatch(input, 'change'); + assert.equal(input.value, 'king'); + done(); + }, 13); + }.bind(this)); + viewModel.bindValue = 'lastName'; + }.bind(this)); + }); + test('value:bind memory leak (#2270)', function () { + var template = stache('
    '); + var vm = new SimpleMap({ foo: '' }); + var frag = template(vm); + var ta = this.fixture; + domMutateNode.appendChild.call(ta, frag); + QUnit.stop(); + testHelpers.afterMutation(function () { + domMutateNode.removeChild.call(ta, ta.firstChild); + testHelpers.afterMutation(function () { + var checkCount = 0; + var checkLifecycleBindings = function () { + var meta = vm[canSymbol.for('can.meta')]; + if (meta.handlers.get([]).length === 0) { + QUnit.ok(true, 'no bindings'); + start(); + } else { + checkCount++; + if (checkCount > 5) { + QUnit.ok(false, 'lifecycle bindings still existed after timeout'); + return start(); + } + setTimeout(checkLifecycleBindings, 1000); + } + }; + checkLifecycleBindings(); + }); + }); + }); + test('converters work (#2299)', function () { + stache.registerConverter('numberToString', { + get: function (source) { + return source() + ''; + }, + set: function (newVal, source) { + source(newVal === '' ? null : +newVal); + } + }); + var template = stache(''); + var map = new SimpleMap({ age: 25 }); + var frag = template(map); + equal(frag.firstChild.value, '25'); + equal(map.get('age'), 25); + map.set('age', 33); + equal(frag.firstChild.value, '33'); + equal(map.get('age'), 33); + frag.firstChild.value = '1'; + domEvents.dispatch(frag.firstChild, 'change'); + stop(); + testHelpers.afterMutation(function () { + start(); + equal(frag.firstChild.value, '1'); + equal(map.get('age'), 1); + }); + }); + testIfRealDocument(' checked:bind should trigger a radiochange event for radio buttons', function () { + var template = stache([ + '{{foo}}', + '{{bar}}' + ].join('')); + var data = new SimpleMap({ + foo: false, + bar: false + }); + var fragment = template(data); + domMutateNode.appendChild.call(this.fixture, fragment); + var self = this; + function child(index) { + return self.fixture.childNodes.item(index); + } + var fooRadio = child(0); + var fooText = child(1); + var barRadio = child(2); + var barText = child(3); + function text(node) { + while (node && node.nodeType !== 3) { + node = node.firstChild; + } + return node && node.nodeValue; + } + fooRadio.checked = true; + domEvents.dispatch(fooRadio, 'change'); + barRadio.checked = true; + domEvents.dispatch(barRadio, 'change'); + equal(text(fooText), 'false', 'foo text is false'); + equal(text(barText), 'true', 'bar text is true'); + equal(data.get('foo'), false); + equal(data.get('bar'), true); + }); + QUnit.test(' change event handler set up when binding on radiochange (#206)', function () { + var template = stache(''); + var map = new SimpleMap({ attending: false }); + var frag = template(map); + var input = frag.firstChild; + input.checked = true; + domEvents.dispatch(input, 'change'); + QUnit.equal(map.get('attending'), true, 'now it is true'); + }); + test(' one-way - DOM - with undefined (#135)', function () { + var data = new SimpleMap({ completed: undefined }), frag = stache('')(data); + domMutateNode.appendChild.call(this.fixture, frag); + var input = this.fixture.getElementsByTagName('input')[0]; + equal(input.checked, false, 'checkbox value should be false for undefined'); + }); + test(' two-way - DOM - with truthy and falsy values binds to checkbox (#1700)', function () { + var data = new SimpleMap({ completed: 1 }), frag = stache('')(data); + domMutateNode.appendChild.call(this.fixture, frag); + var input = this.fixture.getElementsByTagName('input')[0]; + equal(input.checked, true, 'checkbox value bound (via attr check)'); + data.attr('completed', 0); + stop(); + testHelpers.afterMutation(function () { + start(); + equal(input.checked, false, 'checkbox value bound (via attr check)'); + }); + }); + test(' checkboxes with checked:bind bind properly (#628)', function () { + var data = new SimpleMap({ completed: true }), frag = stache('')(data); + domMutateNode.appendChild.call(this.fixture, frag); + var input = this.fixture.getElementsByTagName('input')[0]; + equal(input.checked, data.get('completed'), 'checkbox value bound (via attr check)'); + data.attr('completed', false); + equal(input.checked, data.get('completed'), 'checkbox value bound (via attr uncheck)'); + input.checked = true; + domEvents.dispatch(input, 'change'); + equal(input.checked, true, 'checkbox value bound (via check)'); + equal(data.get('completed'), true, 'checkbox value bound (via check)'); + input.checked = false; + domEvents.dispatch(input, 'change'); + equal(input.checked, false, 'checkbox value bound (via uncheck)'); + equal(data.get('completed'), false, 'checkbox value bound (via uncheck)'); + }); + testIfRealDocument('{{#each values}}{{/each}}'); + var values = new SimpleObservable([ + '1', + '2', + '3', + '4' + ]); + var id = new SimpleObservable('2'); + var frag = template({ + values: values, + id: id + }); + stop(); + var select = frag.firstChild; + var options = select.getElementsByTagName('option'); + testHelpers.afterMutation(function () { + ok(options[1].selected, 'value is initially selected'); + values.set([ + '7', + '2', + '5', + '4' + ]); + testHelpers.afterMutation(function () { + ok(options[1].selected, 'after changing options, value should still be selected'); + start(); + }); + }); + }); + testIfRealDocument(''); + var map = new SimpleMap(); + var frag = template(map); + var ta = this.fixture; + ta.appendChild(frag); + var select = ta.childNodes.item(0); + QUnit.equal(select.selectedIndex, 0, 'Got selected index'); + }); + testIfRealDocument(''); + var map = new SimpleMap({}); + var frag = renderer(map); + equal(frag.firstChild.selectedIndex, 0, 'undefined <- {($first value)}: selectedIndex = 0'); + map.attr('key', 'notfoo'); + stop(); + testHelpers.afterMutation(function () { + start(); + equal(frag.firstChild.selectedIndex, -1, 'notfoo: selectedIndex = -1'); + map.attr('key', 'foo'); + strictEqual(frag.firstChild.selectedIndex, 0, 'foo: selectedIndex = 0'); + map.attr('key', 'notbar'); + stop(); + testHelpers.afterMutation(function () { + start(); + equal(frag.firstChild.selectedIndex, -1, 'notbar: selectedIndex = -1'); + map.attr('key', 'bar'); + strictEqual(frag.firstChild.selectedIndex, 1, 'bar: selectedIndex = 1'); + map.attr('key', 'bar'); + strictEqual(frag.firstChild.selectedIndex, 1, 'bar (no change): selectedIndex = 1'); + }); + }); + }); + test(' ' + '{{#each options}} {{/each}} '); + var frag = template(data); + equal(frag.firstChild.getElementsByTagName('option')[0].selected, false, 'The first empty value is not selected'); + equal(frag.firstChild.getElementsByTagName('option')[2].selected, true, 'One is selected'); + }); + testIfRealDocument('' + '{{#each allColors}}{{/each}}' + ''); + var map = new SimpleMap({ + colors: new DefineList([ + 'red', + 'green' + ]), + allColors: new DefineList([ + { + value: 'red', + label: 'Red' + }, + { + value: 'green', + label: 'Green' + }, + { + value: 'blue', + label: 'Blue' + } + ]) + }); + stop(); + var frag = template(map); + var ta = this.fixture; + ta.appendChild(frag); + var select = ta.getElementsByTagName('select')[0], options = select.getElementsByTagName('option'); + testHelpers.afterMutation(function () { + ok(options[0].selected, 'red should be set initially'); + ok(options[1].selected, 'green should be set initially'); + ok(!options[2].selected, 'blue should not be set initially'); + start(); + }); + }); + test('' + '{{#each countries}}' + '' + '{{/each}}' + ''); + var frag = template(data); + var select = frag.firstChild; + stop(); + testHelpers.afterMutation(function () { + data.get('countries').replace([]); + testHelpers.afterMutation(function () { + data.attr('countries').replace(countries); + equal(data.attr('countryCode'), 'US', 'country kept as USA'); + testHelpers.afterMutation(function () { + ok(select.getElementsByTagName('option')[1].selected, 'USA still selected'); + }); + start(); + }); + }); + }); + testIfRealDocument('' + '' + '' + ''); + var map = new SimpleMap({ color: 'red' }); + var frag = template(map); + var ta = this.fixture; + ta.appendChild(frag); + var inputs = ta.getElementsByTagName('select'); + equal(inputs[0].value, 'red', 'default value set'); + map.set('color', 'green'); + equal(inputs[0].value, 'green', 'alternate value set'); + canReflect.each(ta.getElementsByTagName('option'), function (opt) { + if (opt.value === 'red') { + opt.selected = 'selected'; + } + }); + equal(map.get('color'), 'green', 'not yet updated from input'); + domEvents.dispatch(inputs[0], 'change'); + equal(map.get('color'), 'red', 'updated from input'); + canReflect.each(ta.getElementsByTagName('option'), function (opt) { + if (opt.value === 'green') { + opt.selected = 'selected'; + } + }); + equal(map.get('color'), 'red', 'not yet updated from input'); + domEvents.dispatch(inputs[0], 'change'); + equal(map.get('color'), 'green', 'updated from input'); + }); + testIfRealDocument('' + '' + '' + '' + ''); + var list = new DefineList(); + stop(); + var frag = template({ colors: list }); + var ta = this.fixture; + ta.appendChild(frag); + var select = ta.getElementsByTagName('select')[0], options = select.getElementsByTagName('option'); + setTimeout(function () { + options[0].selected = true; + domEvents.dispatch(select, 'change'); + deepEqual(list.get(), ['red'], 'A DefineList value is set even if none existed'); + options[1].selected = true; + domEvents.dispatch(select, 'change'); + deepEqual(list.get(), [ + 'red', + 'green' + ], 'Adds items to the list'); + options[0].selected = false; + domEvents.dispatch(select, 'change'); + deepEqual(list.get(), ['green'], 'Removes items from the list'); + list.push('ultraviolet'); + options[0].selected = false; + options[1].selected = true; + options[2].selected = true; + ta.removeChild(select); + start(); + }, 1); + }); + QUnit.test('' + '{{#countries}}' + '' + '{{/countries}}' + ''); + var frag = template(data); + var select = frag.firstChild; + stop(); + testHelpers.afterMutation(function () { + data.get('countries').replace([]); + testHelpers.afterMutation(function () { + data.get('countries').replace(countries); + equal(data.get('countryCode'), 'US', 'country kept as USA'); + testHelpers.afterMutation(function () { + ok(select.getElementsByTagName('option')[1].selected, 'USA still selected'); + }); + start(); + }); + }); + }); + testIfRealDocument('' + '{{#each countries}}' + '' + '{{/each}}' + ''); + template(data); + stop(); + testHelpers.afterMutation(function () { + data.attr('countries').replace([]); + testHelpers.afterMutation(function () { + equal(data.get('countryCode'), undefined, 'countryCode set to undefined'); + start(); + }); + }); + }); + testIfRealDocument('' + '' + '{{#each people}}{{/each}}' + '' + ''); + var people = new DefineList([ + 'Justin', + 'Zed', + 'Tom', + 'Paula' + ]); + var vm = new SimpleMap({ + person: 'Brian', + people: people + }); + stop(); + vm.on('person', function (ev, newVal, oldVal) { + ok(false, 'person attribute should not change'); + }); + var frag = template(vm); + equal(vm.attr('person'), 'Brian', 'Person is still set'); + testHelpers.afterMutation(function () { + people.push('Brian'); + testHelpers.afterMutation(function () { + var select = frag.firstChild; + ok(select.lastChild.selected, 'New child should be selected'); + start(); + }); + }); + }); + test('' + '{{#each countries}}' + '' + '{{/each}}' + ''); + var data = new SimpleMap({ + countryCode: 'US', + countries: new DefineList(countries) + }); + var frag = template(data); + data.set('countryCode', 'IND'); + stop(); + testHelpers.afterMutation(function () { + start(); + equal(frag.firstChild.value, 'IND', 'got last updated value'); + }); + }); + testIfRealDocument('' + '' + '' + '' + '' + '' + ''); + var map = new SimpleMap({ + 'color-1': null, + 'color-2': undefined, + 'color-3': '' + }); + stop(); + var frag = template(map); + domMutateNode.appendChild.call(this.fixture, frag); + var nullInput = doc.getElementById('null-select'); + var nullInputOptions = nullInput.getElementsByTagName('option'); + var undefinedInput = doc.getElementById('undefined-select'); + var undefinedInputOptions = undefinedInput.getElementsByTagName('option'); + var stringInput = doc.getElementById('string-select'); + var stringInputOptions = stringInput.getElementsByTagName('option'); + testHelpers.afterMutation(function () { + ok(!nullInputOptions[0].selected, 'default (null) value set'); + ok(undefinedInputOptions[0].selected, 'default (undefined) value set'); + ok(stringInputOptions[0].selected, 'default (\'\') value set'); + start(); + }); + }); + testIfRealDocument(''); + var map = new SimpleMap({ key: null }); + var frag = template(map); + var select = frag.childNodes.item(0); + testHelpers.afterMutation(function () { + equal(select.selectedIndex, -1, 'selectedIndex is 0 because no value exists on the map'); + equal(map.get('key'), null, 'The map\'s value property is set to the select\'s value'); + start(); + }); + stop(); + }); + testIfRealDocument(''); + var map = new SimpleMap(); + var frag = template(map); + var select = frag.childNodes.item(0); + testHelpers.afterMutation(function () { + equal(select.selectedIndex, 0, 'selectedIndex is 0 because no value exists on the map'); + equal(map.attr('value'), 'One', 'The map\'s value property is set to the select\'s value'); + start(); + }); + stop(); + }); + testIfRealDocument('Bi-directional binding among sibling components, new syntax (#325)', function () { + var groupCollapsed = console.groupCollapsed; + if (groupCollapsed) { + console.groupCollapsed = null; + } + var demoContext = new DefineMap({ person: '' }); + var SourceComponentVM = DefineMap.extend('SourceComponentVM', { + defaultPerson: { value: 'John' }, + person: { + set: function (val) { + return val || this.defaultPerson; + } + } + }); + var ClearComponentVM = DefineMap.extend('ClearComponentVM', { + person: 'string', + clearPerson: function () { + this.set('person', ''); + } + }); + MockComponent.extend({ + tag: 'source-component', + viewModel: SourceComponentVM, + template: stache('{{person}}') + }); + MockComponent.extend({ + tag: 'clear-button', + viewModel: ClearComponentVM, + template: stache('{{./person}}') + }); + var demoRenderer = stache('{{./person}}' + '' + ''); + var frag = demoRenderer(demoContext); + var sourceComponentVM = canViewModel(frag.childNodes[1]); + var clearButtonVM = canViewModel(frag.childNodes[2]); + QUnit.equal(frag.childNodes[0].childNodes[0].nodeValue, '', 'demoContext person is empty'); + QUnit.equal(frag.childNodes[1].childNodes[0].childNodes[0].nodeValue, 'John', 'source-component person is default'); + QUnit.equal(frag.childNodes[2].childNodes[1].childNodes[0].nodeValue, '', 'clear-button person is empty'); + sourceComponentVM.person = 'Bob'; + QUnit.equal(frag.childNodes[0].childNodes[0].nodeValue, 'Bob', 'demoContext person set correctly'); + QUnit.equal(frag.childNodes[1].childNodes[0].childNodes[0].nodeValue, 'Bob', 'source-component person set correctly'); + QUnit.equal(frag.childNodes[2].childNodes[1].childNodes[0].nodeValue, 'Bob', 'clear-button person set correctly'); + clearButtonVM.clearPerson(); + QUnit.equal(frag.childNodes[0].childNodes[0].nodeValue, '', 'demoContext person set correctly'); + QUnit.equal(frag.childNodes[1].childNodes[0].childNodes[0].nodeValue, 'John', 'source-component person set correctly'); + QUnit.equal(frag.childNodes[2].childNodes[1].childNodes[0].nodeValue, '', 'clear-button person set correctly'); + if (groupCollapsed) { + console.groupCollapsed = groupCollapsed; + } + }); + testIfRealDocument('Bracket Expression with :to bindings', function () { + var demoContext = new DefineMap({ person: { name: 'Matt' } }); + var SourceComponentVM = DefineMap.extend('SourceComponentVM', { name: { default: 'Kevin' } }); + MockComponent.extend({ + tag: 'source-component', + viewModel: SourceComponentVM, + template: stache('{{name}}') + }); + var demoRenderer = stache(''); + demoRenderer(demoContext); + QUnit.equal(demoContext.person.name, 'Kevin', 'source-component has correct name set'); + }); + }); +}); +/*can-event-dom-enter@2.2.0#can-event-dom-enter*/ +define('can-event-dom-enter@2.2.0#can-event-dom-enter', [ + 'require', + 'exports', + 'module', + 'can-namespace' +], function (require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + var baseEventType = 'keyup'; + function isEnterEvent(event) { + var hasEnterKey = event.key === 'Enter'; + var hasEnterCode = event.keyCode === 13; + return hasEnterKey || hasEnterCode; + } + var enterEvent = { + defaultEventType: 'enter', + addEventListener: function (target, eventType, handler) { + var keyHandler = function (event) { + if (isEnterEvent(event)) { + return handler.apply(this, arguments); + } + }; + var handlerMap = enterEvent._eventTypeHandlerMap[eventType]; + if (!handlerMap) { + handlerMap = enterEvent._eventTypeHandlerMap[eventType] = new Map(); + } + handlerMap.set(handler, keyHandler); + this.addEventListener(target, baseEventType, keyHandler); + }, + removeEventListener: function (target, eventType, handler) { + var handlerMap = enterEvent._eventTypeHandlerMap[eventType]; + if (handlerMap) { + var keyHandler = handlerMap.get(handler); + if (keyHandler) { + handlerMap.delete(handler); + if (handlerMap.size === 0) { + delete enterEvent._eventTypeHandlerMap[eventType]; + } + this.removeEventListener(target, baseEventType, keyHandler); + } + } + }, + _eventTypeHandlerMap: {} + }; + module.exports = namespace.domEventEnter = enterEvent; +}); +/*can-stache-bindings@4.6.4#test/colon/event-test*/ +define('can-stache-bindings@4.6.4#test/colon/event-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + '../helpers', + 'can-stache-bindings', + 'can-stache', + '../mock-component-simple-map', + 'can-simple-map', + 'can-define/list/list', + 'can-simple-observable', + 'can-view-model', + 'can-dom-data-state', + 'can-dom-mutate', + 'can-dom-mutate/node', + 'can-dom-events', + 'can-event-dom-enter' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var testHelpers = require('../helpers'); + require('can-stache-bindings'); + var stache = require('can-stache'); + var MockComponent = require('../mock-component-simple-map'); + var SimpleMap = require('can-simple-map'); + var DefineList = require('can-define/list/list'); + var SimpleObservable = require('can-simple-observable'); + var canViewModel = require('can-view-model'); + var domData = require('can-dom-data-state'); + var domMutate = require('can-dom-mutate'); + var domMutateNode = require('can-dom-mutate/node'); + var domEvents = require('can-dom-events'); + testHelpers.makeTests('can-stache-bindings - colon - event', function (name, doc, enableMO) { + QUnit.test('on:enter', function () { + var enterEvent = require('can-event-dom-enter'); + var undo = domEvents.addEvent(enterEvent); + var template = stache(''); + var called = 0; + var frag = template({ + update: function () { + called++; + equal(called, 1, 'update called once'); + } + }); + var input = frag.childNodes.item(0); + domEvents.dispatch(input, { + type: 'keyup', + keyCode: 38 + }); + domEvents.dispatch(input, { + type: 'keyup', + keyCode: 13 + }); + undo(); + }); + QUnit.test('can call intermediate functions before calling the final function (#1474)', function (assert) { + var ta = this.fixture; + var done = assert.async(); + var template = stache('
    '); + var frag = template({ + does: function () { + return { + some: function () { + return { + thing: function (context) { + assert.ok(typeof context.does === 'function'); + done(); + } + }; + } + }; + } + }); + ta.appendChild(frag); + domEvents.dispatch(doc.getElementById('click-me'), 'click'); + }); + test('two bindings on one element call back the correct method', function () { + expect(2); + var template = stache(''); + var callingFirst = false, callingSecond = false; + var frag = template({ + first: function () { + ok(callingFirst, 'called first'); + }, + second: function () { + ok(callingSecond, 'called second'); + } + }); + var input = frag.childNodes.item(0); + callingFirst = true; + domEvents.dispatch(input, { type: 'mousemove' }); + callingFirst = false; + callingSecond = true; + domEvents.dispatch(input, { type: 'click' }); + }); + test('event behavior event bindings should be removed when the bound element is', function (assert) { + var template = stache('
    {{#if isShowing}}{{/if}}
    '); + var viewModel = new SimpleMap({ isShowing: false }); + viewModel.onClick = function () { + }; + var bindingListenerCount = 0; + var hasAddedBindingListener = false; + var hasRemovedBindingListener = false; + var fragment = template(viewModel); + domMutateNode.appendChild.call(this.fixture, fragment); + var isInputBindingEvent = function (element, eventName) { + return element.nodeName === 'INPUT' && eventName === 'click'; + }; + var realAddEventListener = domEvents.addEventListener; + var realRemoveEventListener = domEvents.removeEventListener; + domEvents.addEventListener = function (target, eventName) { + if (isInputBindingEvent(target, eventName)) { + bindingListenerCount++; + hasAddedBindingListener = true; + } + return realAddEventListener.apply(null, arguments); + }; + domEvents.removeEventListener = function (target, eventName) { + if (isInputBindingEvent(target, eventName)) { + bindingListenerCount--; + hasRemovedBindingListener = true; + } + return realRemoveEventListener.apply(null, arguments); + }; + viewModel.set('isShowing', true); + var span = this.fixture.firstChild.lastChild; + var done = assert.async(); + var undo = domMutate.onNodeRemoval(span, function () { + undo(); + domEvents.addEventListener = realAddEventListener; + domEvents.removeEventListener = realRemoveEventListener; + assert.ok(hasAddedBindingListener, 'An event listener should have been added for the binding'); + assert.ok(hasRemovedBindingListener, 'An event listener should have been removed for the binding'); + var message = bindingListenerCount + ' event listeners were added but not removed'; + if (removeEventListener < 0) { + message = 'Event listeners were removed more than necessary'; + } + assert.equal(bindingListenerCount, 0, message); + done(); + }); + viewModel.set('isShowing', false); + }); + test('on:event throws an error when inside #if block (#1182)', function (assert) { + var done = assert.async(); + var flag = new SimpleObservable(false), clickHandlerCount = 0; + var frag = stache('
    Click
    ')({ + flag: flag, + foo: function () { + clickHandlerCount++; + } + }); + var fixture = this.fixture; + var trig = function () { + var div = fixture.getElementsByTagName('div')[0]; + domEvents.dispatch(div, { type: 'click' }); + }; + domMutateNode.appendChild.call(this.fixture, frag); + trig(); + testHelpers.afterMutation(function () { + equal(clickHandlerCount, 0, 'click handler not called'); + done(); + }); + }); + test('can listen to camelCase events using on:', function () { + QUnit.stop(); + expect(1); + var map = new SimpleMap({ someProp: 'foo' }); + map.someMethod = function () { + QUnit.start(); + ok(true); + }; + var template = stache('
    '); + template(map); + map.set('someProp', 'baz'); + }); + test('can listen to kebab-case events using on:', function () { + QUnit.stop(); + expect(1); + var map = new SimpleMap({ 'some-prop': 'foo' }); + map.someMethod = function () { + QUnit.start(); + ok(true); + }; + var template = stache('
    '); + template(map); + map.set('some-prop', 'baz'); + }); + test('can bind to property on scope using :by:', function () { + stop(); + expect(1); + MockComponent.extend({ tag: 'view-model-able' }); + var template = stache(''); + var map = new SimpleMap({ obj: new SimpleMap({ prop: 'Mercury' }) }); + map.someMethod = function (args) { + start(); + equal(args[0], 'Venus', 'method called'); + }; + template(map); + map.get('obj').set('prop', 'Venus'); + }); + test('can bind to entire scope using :by:this', function () { + stop(); + expect(1); + MockComponent.extend({ tag: 'view-model-able' }); + var template = stache(''); + var map = new SimpleMap({ prop: 'Mercury' }); + map.someMethod = function (newVal) { + start(); + equal(newVal, 'Venus', 'method called'); + }; + template(map); + map.set('prop', 'Venus'); + }); + test('can bind to viewModel using on:vm:prop', function () { + stop(); + expect(1); + var map = new SimpleMap({ prop: 'Mercury' }); + var MySimpleMap = SimpleMap.extend({ + someMethod: function (newVal) { + start(); + equal(newVal, 'Venus', 'method called'); + } + }); + var parent = new MySimpleMap(); + MockComponent.extend({ + tag: 'view-model-able', + viewModel: map + }); + var template = stache(''); + template(parent); + map.attr('prop', 'Venus'); + }); + test('can bind to element using on:el:prop', function () { + stop(); + expect(1); + var map = new SimpleMap({ prop: 'Mercury' }); + var MySimpleMap = SimpleMap.extend({ + someMethod: function () { + start(); + ok(true, 'method called'); + } + }); + var parent = new MySimpleMap(); + MockComponent.extend({ + tag: 'view-model-able', + viewModel: map + }); + var template = stache(''); + var frag = template(parent); + var element = frag.firstChild; + domEvents.dispatch(element, 'prop'); + }); + test('call expressions work (#208)', function () { + expect(2); + stache.registerHelper('addTwo', function (arg) { + return arg + 2; + }); + stache.registerHelper('helperWithArgs', function (arg) { + QUnit.equal(arg, 3, 'got the helper'); + ok(true, 'helper called'); + }); + var template = stache('

    '); + var frag = template({ arg: 1 }); + this.fixture.appendChild(frag); + var p0 = this.fixture.getElementsByTagName('p')[0]; + domEvents.dispatch(p0, 'click'); + }); + QUnit.test('events should bind when using a plain object', function () { + var flip = false; + var template = stache('
    Test
    '); + var frag = template({ + flip: function () { + flip = true; + }, + test: true + }); + domEvents.dispatch(frag.firstChild, 'foo'); + QUnit.ok(flip, 'Plain object method successfully called'); + }); + QUnit.test('scope.arguments gives the event arguments', function () { + var template = stache(''); + var MyMap = SimpleMap.extend({ + doSomething: function (ev, args) { + equal(args[0], ev, 'default arg is ev'); + } + }); + var frag = template(new MyMap()); + var button = frag.firstChild; + domEvents.dispatch(button, 'click'); + }); + test('special values get called', function (assert) { + assert.expect(2); + var done = assert.async(); + var vm = new (SimpleMap.extend('RefSyntaxVM', { + method: function () { + assert.ok(true, 'method called'); + done(); + } + }))(); + vm._refSyntaxFlag = true; + MockComponent.extend({ + tag: 'ref-syntax', + template: stache(''), + viewModel: vm + }); + var template = stache(''); + var frag = template({}); + domMutateNode.appendChild.call(this.fixture, frag); + testHelpers.afterMutation(function () { + var input = doc.getElementsByTagName('input')[0]; + input.value = 'bar'; + domEvents.dispatch(input, 'change'); + var scope = domData.get.call(this.fixture.firstChild).shadowScope; + assert.equal(scope.get('*foo'), 'bar', 'Reference attribute set'); + var refElement = doc.getElementsByTagName('ref-syntax')[0]; + domEvents.dispatch(refElement, 'baz-event'); + }.bind(this)); + }); + QUnit.test('viewModel binding', function () { + MockComponent.extend({ + tag: 'viewmodel-binding', + viewModel: { + makeMyEvent: function () { + this.dispatch('myevent'); + } + } + }); + var frag = stache('')({ + doSomething: function () { + ok(true, 'called!'); + } + }); + canViewModel(frag.firstChild).makeMyEvent(); + }); + QUnit.test('event handlers should run in mutateQueue (#444)', function () { + var list = new DefineList([ + { name: 'A' }, + { name: 'B' }, + { name: 'C' } + ]); + var data = new SimpleMap({ + list: list, + item: list[1], + clearStuff: function () { + this.set('item', null); + this.get('list').splice(1, 1); + } + }); + var template = stache('
    ' + '{{#each list}} ' + '{{^is(., ../item)}}' + '
    {{name}}
    ' + '{{/is}}' + '{{/each}}' + '
    '); + var frag = template(data); + domEvents.dispatch(frag.firstChild, 'click'); + QUnit.ok(true, 'no errors'); + }); + QUnit.test('support simple setters', function () { + var template = stache(''); + var map = new SimpleMap({ + prop: null, + value: 'Value' + }); + var frag = template(map); + var input = frag.childNodes.item(0); + domEvents.dispatch(input, { type: 'click' }); + QUnit.equal(map.get('prop'), 'Value'); + template = stache(''); + map = new SimpleMap({ + prop: null, + value: 'Value' + }); + frag = template(map); + input = frag.childNodes.item(0); + input.value = 'ELEMENT-VALUE'; + domEvents.dispatch(input, { type: 'click' }); + QUnit.equal(map.get('prop'), 'ELEMENT-VALUE'); + template = stache(''); + map = new SimpleMap({ + prop: null, + value: 'Value' + }); + frag = template(map); + input = frag.childNodes.item(0); + domEvents.dispatch(input, { type: 'click' }); + QUnit.equal(map.get('prop'), 3, 'primitives'); + template = stache(''); + map = new SimpleMap({ + prop: null, + returnEight: function () { + return 8; + } + }); + frag = template(map); + input = frag.childNodes.item(0); + domEvents.dispatch(input, { type: 'click' }); + QUnit.equal(map.get('prop'), 8, 'can set to result of calling a function'); + MockComponent.extend({ + tag: 'my-button', + template: stache(''), + viewModel: { clicked: null } + }); + map = new SimpleMap({ clickCount: 0 }); + template = stache(''); + frag = template(map); + var button = frag.firstChild; + var myButton = button.firstChild; + QUnit.equal(typeof button.viewModel.get('clicked'), 'function', 'has function'); + domEvents.dispatch(myButton, { type: 'click' }); + QUnit.equal(map.get('clickCount'), 1, 'function got called'); + }); + }); +}); +/*can-stache-bindings@4.6.4#test/colon/view-model-test*/ +define('can-stache-bindings@4.6.4#test/colon/view-model-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + '../helpers', + 'can-stache-bindings', + 'can-stache', + 'can-simple-map', + '../mock-component-simple-map', + 'can-dom-events', + 'can-dom-mutate', + 'can-dom-mutate/node', + 'can-define/map/map', + 'can-view-callbacks', + 'can-view-model', + 'can-symbol', + 'can-reflect', + 'can-queues', + 'can-test-helpers', + 'can-stache-bindings', + 'can-view-scope' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var testHelpers = require('../helpers'); + require('can-stache-bindings'); + var stache = require('can-stache'); + var SimpleMap = require('can-simple-map'); + var MockComponent = require('../mock-component-simple-map'); + var domEvents = require('can-dom-events'); + var domMutate = require('can-dom-mutate'); + var domMutateNode = require('can-dom-mutate/node'); + var DefineMap = require('can-define/map/map'); + var viewCallbacks = require('can-view-callbacks'); + var canViewModel = require('can-view-model'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + var queues = require('can-queues'); + var canTestHelpers = require('can-test-helpers'); + var stacheBindings = require('can-stache-bindings'); + var Scope = require('can-view-scope'); + testHelpers.makeTests('can-stache-bindings - colon - ViewModel', function (name, doc, enableMO) { + QUnit.test('on:el:click works inside {{#if}} on element with a viewModel (#279)', function () { + var map = new SimpleMap({}); + var MySimpleMap = SimpleMap.extend({ + show: true, + method: function () { + ok(true, 'method called'); + } + }); + var parent = new MySimpleMap(); + MockComponent.extend({ + tag: 'view-model-able', + viewModel: map + }); + var template = stache(''); + var frag = template(parent); + var el = frag.firstChild; + domEvents.dispatch(el, 'click'); + }); + QUnit.test('vm:prop:to/:from/:bind work (#280)', function () { + var vm1 = new SimpleMap({ value: 'vm1' }); + var vm2 = new SimpleMap({ value: 'vm2' }); + var vm3 = new SimpleMap({ value: 'vm3' }); + MockComponent.extend({ + tag: 'comp-1', + viewModel: vm1 + }); + MockComponent.extend({ + tag: 'comp-2', + viewModel: vm2 + }); + MockComponent.extend({ + tag: 'comp-3', + viewModel: vm3 + }); + var template = stache('' + '' + ''); + var scope = new SimpleMap({ + scope1: 'scope1', + scope2: 'scope2', + scope3: 'scope3' + }); + template(scope); + equal(scope.attr('scope1'), 'vm1', 'vm:value:to - scope value set from vm'); + vm1.attr('value', 'vm4'); + equal(scope.attr('scope1'), 'vm4', 'vm:value:to - scope updated when vm changes'); + scope.attr('scope1', 'scope4'); + equal(vm1.attr('value'), 'vm4', 'vm:value:to - vm not updated when scope changes'); + equal(vm2.attr('value'), 'scope2', 'vm:value:from - vm value set from scope'); + scope.attr('scope2', 'scope5'); + equal(vm2.attr('value'), 'scope5', 'vm:value:from - vm updated when scope changes'); + vm2.attr('value', 'vm5'); + equal(scope.attr('scope2'), 'scope5', 'vm:value:from - scope not updated when vm changes'); + equal(vm3.attr('value'), 'scope3', 'vm:value:bind - vm value set from scope'); + scope.attr('scope3', 'scope6'); + equal(vm3.attr('value'), 'scope6', 'vm:value:bind - vm updated when scope changes'); + vm3.attr('value', 'vm6'); + equal(scope.attr('scope3'), 'vm6', 'vm:value:bind - scope updated when vm changes'); + }); + canTestHelpers.dev.devOnlyTest('Warning happens when changing the map that a to-parent binding points to.', function () { + var tagName = 'merge-warn-test'; + delete viewCallbacks._tags[tagName]; + expect(2); + var step1 = { 'baz': 'quux' }; + var overwrite = { 'plonk': 'waldo' }; + var teardown = canTestHelpers.dev.willWarn('can-stache-key: Merging data into "bar" because its parent is non-observable'); + var viewModel; + MockComponent.extend({ + tag: tagName, + viewModel: function () { + return viewModel = new SimpleMap({ 'foo': new SimpleMap({}) }); + } + }); + var template = stache(''); + var data = { bar: new SimpleMap(step1) }; + this.fixture.appendChild(template(data)); + viewModel.set('foo', overwrite); + deepEqual(data.bar.get(), { 'plonk': 'waldo' }, 'sanity check: parent binding set (default map -> default map)'); + QUnit.equal(teardown(), 1, 'warning shown'); + }); + QUnit.test('changing a scope property calls registered stache helper\'s returned function', function () { + expect(1); + stop(); + var scope = new SimpleMap({ test: 'testval' }); + MockComponent.extend({ + tag: 'test-component', + viewModel: scope, + template: stache('Hello world') + }); + stache.registerHelper('propChangeEventStacheHelper', function () { + return function () { + start(); + ok(true, 'helper\'s returned function called'); + }; + }); + var template = stache(''); + template({}); + scope.set('test', 'changed'); + }); + test('one-way pass computes to components with ~', function (assert) { + expect(6); + MockComponent.extend({ tag: 'foo-bar' }); + var baseVm = new SimpleMap({ foo: 'bar' }); + this.fixture.appendChild(stache('')(baseVm)); + var vm = canViewModel(this.fixture.firstChild); + ok(vm.get('compute')[canSymbol.for('can.getValue')], 'observable returned'); + equal(vm.get('compute')(), 'bar', 'Compute has correct value'); + canReflect.onValue(vm.get('compute'), function () { + ok(true, 'Change handler called'); + }); + baseVm.set('foo', 'quux'); + equal(vm.get('compute')(), 'quux', 'Compute updates'); + vm.get('compute')('xyzzy'); + equal(baseVm.get('foo'), 'xyzzy', 'Compute does update the other direction'); + }); + test('Child bindings updated before parent (#2252)', function () { + var template = stache('{{#eq page \'view\'}}{{/eq}}'); + MockComponent.extend({ + tag: 'child-binder', + template: stache(''), + viewModel: function (props) { + var map = new SimpleMap(props); + canReflect.assignSymbols(map, { + 'can.setKeyValue': function (key, value) { + if (key === 'page') { + equal(value, 'view', 'value should not be edit'); + } else { + QUnit.equal(key, 'title', 'title was set, we are trapping right'); + } + this.set(key, value); + } + }); + return map; + } + }); + var data = new SimpleMap({ page: 'view' }); + template(data); + data.set('title', 'foo'); + queues.batch.start(); + data.set('page', 'edit'); + queues.batch.stop(); + }); + test('backtrack path in to-parent bindings (#2132)', function () { + MockComponent.extend({ + tag: 'parent-export', + viewModel: { value: 'VALUE' } + }); + var template = stache('{{#innerMap}}{{/innerMap}}'); + var data = new SimpleMap({ innerMap: new SimpleMap({}) }); + template(data); + equal(data.get('parentValue'), 'VALUE', 'set on correct context'); + equal(data.get('innerMap').get('parentValue'), undefined, 'nothing on innerMap'); + }); + test('function reference to child binding (#2116)', function () { + expect(2); + var template = stache(''); + MockComponent.extend({ + tag: 'foo-bar', + viewModel: {} + }); + var VM = SimpleMap.extend({}); + var vm = new VM({}); + var frag = template(vm); + vm.attr('parent', function () { + ok(false, 'should not be called'); + }); + equal(typeof canViewModel(frag.firstChild).attr('child'), 'function', 'to child binding'); + template = stache(''); + vm = new VM({}); + frag = template(vm); + canViewModel(frag.firstChild).attr('method', function () { + ok(false, 'method should not be called'); + }); + equal(typeof vm.get('vmMethod'), 'function', 'parent export function'); + }); + test('setter only gets called once (#2117)', function () { + expect(1); + var VM = SimpleMap.extend({ + attr: function (prop, val) { + if (prop === 'bar') { + equal(val, 'BAR'); + } + return SimpleMap.prototype.attr.apply(this, arguments); + } + }); + MockComponent.extend({ + tag: 'foo-bar', + viewModel: VM + }); + var template = stache(''); + template(new SimpleMap({ bar: 'BAR' })); + }); + test('function reference to child (#2116)', function () { + expect(2); + var template = stache(''); + MockComponent.extend({ + tag: 'foo-bar', + viewModel: { + method: function () { + ok(false, 'should not be called'); + } + } + }); + var VM = SimpleMap.extend({ + parent: function () { + ok(false, 'should not be called'); + } + }); + var vm = new VM({}); + var frag = template(vm); + equal(typeof canViewModel(frag.firstChild).attr('child'), 'function', 'to child binding'); + template = stache(''); + vm = new VM({}); + template(vm); + ok(typeof vm.attr('vmMethod') === 'function', 'parent export function'); + }); + test('exporting methods (#2051)', function () { + expect(2); + MockComponent.extend({ + tag: 'foo-bar', + viewModel: { + method: function () { + ok(true, 'foo called'); + return 5; + } + } + }); + var template = stache('{{scope.vars.refKey()}}'); + var frag = template({}); + equal(frag.lastChild.nodeValue, '5'); + }); + test('one way - child to parent - importing viewModel hyphenatedProp:to="test"', function () { + MockComponent.extend({ + tag: 'import-prop-scope', + template: stache('Hello {{userName}}'), + viewModel: { + userName: 'David', + age: 7, + updateName: function () { + this.set('userName', 'Justin'); + } + } + }); + MockComponent.extend({ + tag: 'import-prop-parent', + template: stache('' + '
    Imported: {{test}}
    ') + }); + var template = stache(''); + var frag = template({}); + var importPropParent = frag.firstChild; + var importPropScope = importPropParent.getElementsByTagName('import-prop-scope')[0]; + canViewModel(importPropScope).updateName(); + var importPropParentViewModel = canViewModel(importPropParent); + equal(importPropParentViewModel.get('test'), 'Justin', 'got hyphenated prop'); + equal(importPropParentViewModel.get('childComponent'), canViewModel(importPropScope), 'got view model'); + }); + test('one way - child to parent - importing viewModel prop:to="test"', function () { + MockComponent.extend({ + tag: 'import-prop-scope', + template: stache('Hello {{name}}'), + viewModel: { + name: 'David', + age: 7 + } + }); + MockComponent.extend({ + tag: 'import-prop-parent', + template: stache('' + '
    Imported: {{test}}
    ') + }); + var template = stache(''); + var frag = template({}); + equal(frag.childNodes.item(0).childNodes.item(1).innerHTML, 'Imported: David', '{name} component scope imported into variable'); + }); + test('one-way - child to parent - viewModel', function () { + MockComponent.extend({ + tag: 'view-model-able', + viewModel: function () { + return new SimpleMap({ viewModelProp: 'Mercury' }); + } + }); + var template = stache(''); + var map = new SimpleMap({ scopeProp: 'Venus' }); + var frag = template(map); + var viewModel = canViewModel(frag.firstChild); + equal(viewModel.get('viewModelProp'), 'Mercury', 'initial value kept'); + equal(map.get('scopeProp'), 'Mercury', 'initial value set on parent'); + viewModel.set('viewModelProp', 'Earth'); + equal(map.get('scopeProp'), 'Earth', 'binding from child to parent'); + map.set('scopeProp', 'Mars'); + equal(viewModel.get('viewModelProp'), 'Earth', 'no binding from parent to child'); + }); + test('one-way - child to parent - viewModel - with converters', function () { + MockComponent.extend({ + tag: 'view-model-able', + viewModel: function () { + return new SimpleMap({ viewModelProp: 'Mercury' }); + } + }); + stache.addConverter('upper-case', { + get: function (fooCompute) { + return ('' + canReflect.getValue(fooCompute)).toUpperCase(); + }, + set: function (newVal, fooCompute) { + canReflect.setValue(fooCompute, ('' + newVal).toUpperCase()); + } + }); + var template = stache(''); + var map = new SimpleMap({ scopeProp: 'Venus' }); + var frag = template(map); + var viewModel = canViewModel(frag.firstChild); + equal(viewModel.get('viewModelProp'), 'Mercury', 'initial value kept'); + equal(map.get('scopeProp'), 'MERCURY', 'initial value set on parent, but upper cased'); + viewModel.set('viewModelProp', 'Earth'); + equal(map.get('scopeProp'), 'EARTH', 'binding from child to parent updated'); + map.set('scopeProp', 'Mars'); + equal(viewModel.get('viewModelProp'), 'Earth', 'no binding from parent to child'); + }); + test('one-way - parent to child - viewModel', function () { + var template = stache('
    '); + var map = new SimpleMap({ scopeProp: 'Venus' }); + var frag = template(map); + var viewModel = canViewModel(frag.firstChild); + equal(viewModel.attr('viewModelProp'), 'Venus', 'initial value set'); + viewModel.attr('viewModelProp', 'Earth'); + equal(map.attr('scopeProp'), 'Venus', 'no binding from child to parent'); + map.attr('scopeProp', 'Mars'); + equal(viewModel.attr('viewModelProp'), 'Mars', 'binding from parent to child'); + }); + test('two-way - reference - child:bind="scope.vars.ref" (#1700)', function () { + var data = new SimpleMap({ person: new SimpleMap({ name: new SimpleMap({}) }) }); + MockComponent.extend({ + tag: 'reference-export', + viewModel: function () { + return new SimpleMap({ tag: 'reference-export' }); + } + }); + MockComponent.extend({ + tag: 'ref-import', + viewModel: function () { + return new SimpleMap({ tag: 'ref-import' }); + } + }); + var template = stache('' + ' {{helperToGetScope()}}'); + var scope; + var frag = template(data, { + helperToGetScope: function (options) { + scope = options.scope; + } + }); + var refExport = canViewModel(frag.firstChild); + var refImport = canViewModel(frag.firstChild.nextSibling); + refExport.set('name', 'v1'); + equal(scope.peek('scope.vars.refName'), 'v1', 'reference scope updated'); + equal(refImport.get('name'), 'v1', 'updated ref-import'); + refImport.set('name', 'v2'); + equal(refExport.get('name'), 'v2', 'updated ref-export'); + equal(scope.peek('scope.vars.refName'), 'v2', 'actually put in refs scope'); + }); + test('one-way - DOM - parent value undefined (#189)', function () { + MockComponent.extend({ + tag: 'toggle-button', + viewModel: function () { + var vm = new SimpleMap({ value: false }); + vm.toggle = function () { + this.set('value', !this.get('value')); + }; + return vm; + }, + template: stache('') + }); + var template = stache(''); + var fragment = template({}); + domMutateNode.appendChild.call(this.fixture, fragment); + var button = this.fixture.getElementsByTagName('button')[0]; + function text(node) { + while (node && node.nodeType !== 3) { + node = node.firstChild; + } + return node && node.nodeValue; + } + equal(text(button), 'false', 'Initial value is "false"'); + domEvents.dispatch(button, 'click'); + equal(text(button), 'true', 'Value is "true" after first click'); + domEvents.dispatch(button, 'click'); + equal(text(button), 'false', 'Value is "false" after second click'); + }); + test('two way - viewModel (#1700)', function () { + var template = stache('
    '); + var map = new SimpleMap({ scopeProp: 'Hello' }); + var scopeMapSetCalled = 0; + var origMapSetKeyValue = map[canSymbol.for('can.setKeyValue')]; + map[canSymbol.for('can.setKeyValue')] = function (attrName, value) { + if (typeof attrName === 'string' && arguments.length > 1) { + scopeMapSetCalled++; + } + return origMapSetKeyValue.apply(this, arguments); + }; + var frag = template(map); + var viewModel = canViewModel(frag.firstChild); + equal(scopeMapSetCalled, 0, 'set is not called on scope map'); + equal(viewModel.get('viewModelProp'), 'Hello', 'initial value set'); + viewModel = canViewModel(frag.firstChild); + var viewModelSetCalled = 1; + var origViewModelSet = viewModel[canSymbol.for('can.setKeyValue')]; + viewModel[canSymbol.for('can.setKeyValue')] = function (attrName) { + if (typeof attrName === 'string' && arguments.length > 1) { + viewModelSetCalled++; + } + return origViewModelSet.apply(this, arguments); + }; + viewModel.set('viewModelProp', 'HELLO'); + equal(map.get('scopeProp'), 'HELLO', 'binding from child to parent'); + equal(scopeMapSetCalled, 1, 'set is called on scope map'); + equal(viewModelSetCalled, 2, 'set is called viewModel'); + map.set('scopeProp', 'WORLD'); + equal(viewModel.get('viewModelProp'), 'WORLD', 'binding from parent to child'); + equal(scopeMapSetCalled, 1, 'can.setKey is not called again on scope map'); + equal(viewModelSetCalled, 3, 'set is called again on viewModel'); + }); + test('standard attributes should not set viewModel props', function () { + MockComponent.extend({ + tag: 'test-elem', + viewModel: SimpleMap + }); + var template = stache(''); + var frag = template(new SimpleMap({ bar: true })); + var vm = canViewModel(frag.firstChild); + equal(vm.get('foo'), undefined); + }); + test('set string on the viewModel', function () { + expect(2); + var ViewModel = DefineMap.extend({ + foo: { + type: 'string', + set: function (val) { + equal(val, 'bar'); + } + }, + baz: { + type: 'string', + set: function (val) { + equal(val, 'qux'); + } + } + }); + MockComponent.extend({ + tag: 'test-elem', + viewModel: ViewModel + }); + var template = stache(''); + template(); + }); + test('viewModel behavior event bindings should be removed when the bound element is', function (assert) { + MockComponent.extend({ + tag: 'view-model-binder', + viewModel: {}, + template: stache('') + }); + var done = assert.async(); + var onNodeAttributeChange = domMutate.onNodeAttributeChange; + var attributeChangeCount = 0; + var isAttributeChangeTracked = false; + var isTarget = function (target) { + return target.nodeName === 'VIEW-MODEL-BINDER'; + }; + domMutate.onNodeAttributeChange = function (node) { + if (!isTarget(node)) { + return onNodeAttributeChange.apply(null, arguments); + } + attributeChangeCount++; + isAttributeChangeTracked = true; + var disposal = onNodeAttributeChange.apply(null, arguments); + return function () { + attributeChangeCount--; + return disposal(); + }; + }; + var viewModel = new SimpleMap({ + isShowing: true, + bar: 'baz' + }); + var template = stache('
    {{#if isShowing}}
    {{/if}}
    '); + var fragment = template(viewModel); + domMutateNode.appendChild.call(this.fixture, fragment); + var hr = this.fixture.firstChild.lastChild; + var removalDisposal = domMutate.onNodeRemoval(hr, function () { + removalDisposal(); + domMutate.onNodeAttributeChange = onNodeAttributeChange; + assert.ok(isAttributeChangeTracked, 'Attribute foo:bind="bar" should be tracked'); + assert.equal(attributeChangeCount, 0, 'all attribute listeners should be disposed'); + done(); + }); + viewModel.attr('isShowing', false); + }); + canTestHelpers.dev.devOnlyTest('warning displayed when using @', function () { + expect(3); + var teardown = canTestHelpers.dev.willWarn('myTemplate.stache:1: functions are no longer called by default so @ is unnecessary in \'@scope.vars.refKey\'.'); + MockComponent.extend({ + tag: 'foo-bar', + viewModel: { + method: function () { + ok(true, 'foo called'); + return 5; + } + } + }); + var template = stache('myTemplate.stache', '{{scope.vars.refKey()}}'); + var frag = template({}); + equal(frag.lastChild.nodeValue, '5'); + equal(teardown(), 2, 'warnings displayed for read and write'); + }); + QUnit.test('bindings.viewModel makeViewModel gets passed the binding state', function () { + var element = document.createElement('bindings-viewmodel'); + element.setAttribute('age:from', 'years'); + stacheBindings.behaviors.viewModel(element, { scope: new Scope({ years: 22 }) }, function (data, hasDataBinding, bindingState) { + QUnit.equal(bindingState.isSettingOnViewModel, true, 'isSettingOnViewModel called with correct value'); + QUnit.ok(!bindingState.isSettingViewModel, 'isSettingOnViewModel called with correct value'); + }, {}); + var element2 = document.createElement('bindings-viewmodel'); + element2.setAttribute('this:from', 'user'); + stacheBindings.behaviors.viewModel(element2, { scope: new Scope({ user: { name: 'me' } }) }, function (data, hasDataBinding, bindingState) { + QUnit.ok(!bindingState.isSettingOnViewModel, 'isSettingOnViewModel called with correct value'); + QUnit.ok(bindingState.isSettingViewModel, 'isSettingOnViewModel called with correct value'); + }, {}); + }); + QUnit.test('double parent update', function () { + var parentVM = new SimpleMap({ parentValue: '' }); + MockComponent.extend({ + tag: 'parent-that-gets', + viewModel: parentVM, + template: stache('') + }); + MockComponent.extend({ + tag: 'child-that-updates', + viewModel: new SimpleMap({ child: 'CHILD1' }), + template: stache('') + }); + MockComponent.extend({ + tag: 'gc-that-updates', + viewModel: new SimpleMap({ gc: 'gc' }) + }); + var template = stache('{{# if(this.show) }}{{/if}}'); + var root = new SimpleMap({ show: false }); + template(root); + root.set('show', true); + QUnit.equal(parentVM.get('parentValue'), 'gc'); + }); + }); +}); +/*can-stache-bindings@4.6.4#test/colon/hybrid-test*/ +define('can-stache-bindings@4.6.4#test/colon/hybrid-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + '../helpers', + 'can-stache-bindings', + 'can-stache', + 'can-simple-map', + 'can-dom-events' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var testHelpers = require('../helpers'); + require('can-stache-bindings'); + var stache = require('can-stache'); + var SimpleMap = require('can-simple-map'); + var domEvents = require('can-dom-events'); + testHelpers.makeTests('can-stache-bindings - colon - hybrids', function (name, doc, enableMO) { + test('value:to:on:click and on:click:value:to work (#269)', function () { + var template = stache('' + ''); + var map = new SimpleMap({}); + var frag = template(map); + var ta = this.fixture; + ta.appendChild(frag); + var bindFirstInput = ta.getElementsByTagName('input')[0]; + bindFirstInput.value = '22'; + domEvents.dispatch(bindFirstInput, 'click'); + QUnit.equal(map.get('theProp'), '22'); + var eventFirstInput = ta.getElementsByTagName('input')[1]; + eventFirstInput.value = '23'; + domEvents.dispatch(eventFirstInput, 'click'); + QUnit.equal(map.get('theProp'), '23'); + }); + QUnit.test('on:input:value:to works (#289)', function () { + var scope = new SimpleMap({ myProp: '' }); + var renderer = stache(''); + var view = renderer(scope); + var ta = this.fixture; + ta.appendChild(view); + var inputTo = ta.getElementsByTagName('input')[0]; + inputTo.value = 'wurld'; + domEvents.dispatch(inputTo, 'input'); + equal(scope.get('myProp'), 'wurld', 'Got the value on the scope'); + }); + QUnit.test('on:input:value:to does not initialize values (#289)', function () { + try { + stache('')(); + ok(true, 'renderer was made without error'); + } catch (e) { + ok(false, e.message); + } + }); + QUnit.test('on:input:value:bind should initialize values (#457)', function () { + var frag = stache('')({ foo: 'bar' }); + var input = frag.firstChild; + QUnit.equal(input.value, 'bar', 'initialized to the parent value'); + }); + }); +}); +/*can-stache-bindings@4.6.4#test/colon/dependencies-test*/ +define('can-stache-bindings@4.6.4#test/colon/dependencies-test', [ + 'require', + 'exports', + 'module', + '@steal', + 'steal-qunit', + 'can-simple-map', + 'can-view-model', + 'can-reflect-dependencies', + 'can-reflect', + 'can-stache', + 'can-stache-bindings' +], function (require, exports, module) { + var steal = require('@steal'); + var QUnit = require('steal-qunit'); + var SimpleMap = require('can-simple-map'); + var canViewModel = require('can-view-model'); + var canReflectDeps = require('can-reflect-dependencies'); + var canReflect = require('can-reflect'); + var stache = require('can-stache'); + require('can-stache-bindings'); + var browserSupportsAutomaticallyNamedConstructors = function () { + var C = function C() { + }; + var c = new C(); + return c.constructor.name === 'C'; + }(); + QUnit.module('bindings dependencies', { + beforeEach: function () { + this.fixture = document.getElementById('qunit-fixture'); + }, + afterEach: function () { + document.getElementById('qunit-fixture').innerHTML = ''; + } + }); + var devOnlyTest = steal.isEnv('production') ? QUnit.skip : QUnit.test; + devOnlyTest('parent to child dependencies', function (assert) { + var template = stache(''); + var map = new SimpleMap(); + var frag = template(map); + var ta = this.fixture; + ta.appendChild(frag); + var input = ta.getElementsByTagName('input')[0]; + var inputDeps = canReflectDeps.getDependencyDataOf(input, 'value').whatChangesMe; + assert.ok(inputDeps.mutate.valueDependencies.size, 'the input should have mutation dependencies'); + var attributeObservation = canReflect.toArray(inputDeps.mutate.valueDependencies)[0]; + var attributeObservationDeps = canReflectDeps.getDependencyDataOf(attributeObservation).whatChangesMe; + assert.ok(attributeObservationDeps.derive.keyDependencies.get(input).has('value'), 'the input\'s \'value\' attribute should be a dependency of the attribute observation'); + assert.ok(attributeObservationDeps.mutate.valueDependencies.size, 'the attribute observation should have mutation dependencies'); + var scopeKeyData = canReflect.toArray(attributeObservationDeps.mutate.valueDependencies)[0]; + var scopeKeyDataDeps = canReflectDeps.getDependencyDataOf(scopeKeyData).whatChangesMe; + assert.ok(!scopeKeyDataDeps.mutate, 'the attribute observation should NOT be a dependency of scopeKeyData'); + }); + devOnlyTest('parent to child - map', function (assert) { + var template = stache(''); + var map = new SimpleMap({ age: 10 }); + var frag = template(map); + var ta = this.fixture; + ta.appendChild(frag); + var ageDeps = canReflectDeps.getDependencyDataOf(map, 'age').whatChangesMe; + assert.ok(ageDeps.mutate.valueDependencies.size, 'map.age should have mutation dependencies'); + var scopeKeyData = canReflect.toArray(ageDeps.mutate.valueDependencies)[0]; + var scopeKeyDataDeps = canReflectDeps.getDependencyDataOf(scopeKeyData).whatIChange; + assert.ok(scopeKeyDataDeps.mutate.valueDependencies.size, 'the scopeKeyData should have [whatIChange] mutation dependencies'); + var attributeObservable = canReflect.toArray(scopeKeyDataDeps.mutate.valueDependencies)[0]; + if (browserSupportsAutomaticallyNamedConstructors) { + assert.equal(attributeObservable.constructor.name, 'AttributeObservable', 'scopeKeyData affects the AttributeObservable instance'); + } + }); + devOnlyTest('child to parent dependencies', function (assert) { + var template = stache(''); + var scope = new SimpleMap({ age: 10 }); + var frag = template(scope); + var ta = this.fixture; + ta.appendChild(frag); + var input = ta.getElementsByTagName('input')[0]; + var inputDeps = canReflectDeps.getDependencyDataOf(input, 'value').whatChangesMe; + assert.ok(inputDeps.mutate.valueDependencies.size, 'the input should have mutation dependencies'); + var attributeObservation = canReflect.toArray(inputDeps.mutate.valueDependencies)[0]; + var attributeObservationDeps = canReflectDeps.getDependencyDataOf(attributeObservation); + assert.ok(attributeObservationDeps.whatChangesMe.derive.keyDependencies.get(input).has('value'), 'the input\'s \'value\' attribute should be a dependency of the attribute observation'); + assert.ok(attributeObservationDeps.whatIChange.mutate.valueDependencies.size, 'The attribute observable changes ScopeObservable'); + var scopeObservable = canReflect.toArray(attributeObservationDeps.whatIChange.mutate.valueDependencies)[0]; + var scopeObservableDeps = canReflectDeps.getDependencyDataOf(scopeObservable).whatIChange.mutate; + assert.ok(scopeObservableDeps.keyDependencies.get(scope).has('age'), 'The scope observable changes the scope\'s \'age\' property'); + }); + devOnlyTest('attribute cross binding dependencies', function (assert) { + var template = stache(''); + var scope = new SimpleMap({ age: 8 }); + var frag = template(scope); + var ta = this.fixture; + ta.appendChild(frag); + var input = ta.getElementsByTagName('input')[0]; + var inputDeps = canReflectDeps.getDependencyDataOf(input, 'value').whatChangesMe; + assert.ok(inputDeps.mutate.valueDependencies.size, 'the input should have mutation dependencies'); + var attributeObservation = canReflect.toArray(inputDeps.mutate.valueDependencies)[0]; + var attributeObservationDeps = canReflectDeps.getDependencyDataOf(attributeObservation).whatChangesMe; + assert.ok(attributeObservationDeps.derive.keyDependencies.get(input).has('value'), 'the input\'s \'value\' attribute should be a dependency of the attribute observation'); + assert.ok(attributeObservationDeps.mutate.valueDependencies.size, 'the attribute observation should have mutation dependencies'); + var scopeKeyData = canReflect.toArray(attributeObservationDeps.mutate.valueDependencies)[0]; + var scopeKeyDataDeps = canReflectDeps.getDependencyDataOf(scopeKeyData).whatChangesMe; + assert.ok(scopeKeyDataDeps.mutate.valueDependencies.has(attributeObservation), 'the attribute observation should be a dependency of scopeKeyData'); + }); + devOnlyTest('view model parent to child binding', function (assert) { + var template = stache('
    '); + var map = new SimpleMap({ scopeProp: 'Venus' }); + var ta = this.fixture; + ta.appendChild(template(map)); + var vm = canViewModel(ta.getElementsByTagName('div')[0]); + var vmDeps = canReflectDeps.getDependencyDataOf(vm, 'viewModelProp').whatChangesMe; + assert.ok(vmDeps.mutate.valueDependencies.size, 'The viewmodel property should have value dependencies'); + var settableObservable = canReflect.toArray(vmDeps.mutate.valueDependencies)[0]; + var settableObservableDeps = canReflectDeps.getDependencyDataOf(settableObservable).whatChangesMe; + assert.ok(settableObservableDeps.mutate.valueDependencies.size, 'The settable observable should have value dependencies'); + var scopeKeyData = canReflect.toArray(settableObservableDeps.mutate.valueDependencies)[0]; + var scopeKeyDataObservationDeps = canReflectDeps.getDependencyDataOf(scopeKeyData.observation).whatChangesMe; + var scopeKeyDataDeps = canReflectDeps.getDependencyDataOf(scopeKeyData).whatChangesMe; + assert.ok(scopeKeyDataObservationDeps.derive.keyDependencies.get(map).has('scopeProp'), 'The ScopeKeyData\'s internal observation is bound to map.scopeProp'); + assert.ok(scopeKeyDataDeps.derive.valueDependencies.has(scopeKeyData.observation), 'The ScopeKeyData is bound to its internal observation'); + }); + devOnlyTest('view model child to parent binding', function (assert) { + var template = stache('
    '); + var map = new SimpleMap({ scopeProp: 'Venus' }); + var ta = this.fixture; + ta.appendChild(template(map)); + var vm = canViewModel(ta.getElementsByTagName('div')[0]); + var vmDeps = canReflectDeps.getDependencyDataOf(vm, 'viewModelProp').whatChangesMe; + assert.ok(vmDeps.mutate.valueDependencies.size, 'The viewmodel property should have value dependencies'); + var settableObservable = canReflect.toArray(vmDeps.mutate.valueDependencies)[0]; + var settableObservableDeps = canReflectDeps.getDependencyDataOf(settableObservable).whatIChange; + assert.ok(settableObservableDeps.mutate.valueDependencies.size, 'The settable observable should have value dependencies'); + var scopeObs = canReflect.toArray(settableObservableDeps.mutate.valueDependencies)[0]; + var scopeObsDeps = canReflectDeps.getDependencyDataOf(scopeObs).whatIChange; + assert.ok(scopeObsDeps.mutate.keyDependencies.get(map).has('scopeProp'), 'The ObservableFromScope is bound to map.scopeProp'); + }); +}); +/*can-stache-bindings@4.6.4#test/colon/tests*/ +define('can-stache-bindings@4.6.4#test/colon/tests', [ + 'require', + 'exports', + 'module', + './basics-test', + './element-test', + './event-test', + './view-model-test', + './hybrid-test', + './dependencies-test' +], function (require, exports, module) { + require('./basics-test'); + require('./element-test'); + require('./event-test'); + require('./view-model-test'); + require('./hybrid-test'); + require('./dependencies-test'); +}); +/*can-stache-bindings@4.6.4#test/data/tests*/ +define('can-stache-bindings@4.6.4#test/data/tests', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + '../helpers', + 'can-stache-bindings', + 'can-stache', + 'can-simple-map', + 'can-dom-mutate', + 'can-dom-mutate/node', + 'can-globals' +], function (require, exports, module) { + (function (global, require, exports, module) { + var QUnit = require('steal-qunit'); + var testHelpers = require('../helpers'); + require('can-stache-bindings'); + var stache = require('can-stache'); + var SimpleMap = require('can-simple-map'); + var domMutate = require('can-dom-mutate'); + var domMutateNode = require('can-dom-mutate/node'); + var globals = require('can-globals'); + testHelpers.makeTests('can-stache-bindings - data', function (name, doc, enableMO, testIfRealDocument) { + QUnit.test('event bindings should be removed when the bound element is', function (assert) { + var done = assert.async(); + var template = stache('
    {{#if isShowing}}
    {{/if}}
    '); + var viewModel = new SimpleMap({ + isShowing: true, + bar: 'baz' + }); + var isTarget = function (target) { + return target.nodeName === 'SPAN'; + }; + var attributeChangeCount = 0; + var isAttributeChangeTracked = false; + var onNodeAttributeChange = domMutate.onNodeAttributeChange; + domMutate.onNodeAttributeChange = function (node) { + if (!isTarget(node)) { + return onNodeAttributeChange.apply(null, arguments); + } + attributeChangeCount++; + isAttributeChangeTracked = true; + var disposal = onNodeAttributeChange.apply(null, arguments); + return function () { + attributeChangeCount--; + return disposal(); + }; + }; + var removalCount = 0; + var isRemovalTracked = false; + var onNodeRemoval = domMutate.onNodeRemoval; + domMutate.onNodeRemoval = function (node) { + if (!isTarget(node)) { + return onNodeRemoval.apply(null, arguments); + } + removalCount++; + isRemovalTracked = true; + var disposal = onNodeRemoval.apply(null, arguments); + return function () { + removalCount--; + return disposal(); + }; + }; + var fragment = template(viewModel); + domMutateNode.appendChild.call(this.fixture, fragment); + var hr = this.fixture.firstChild.lastChild; + var removalDisposal = domMutate.onNodeRemoval(hr, function () { + removalDisposal(); + domMutate.onNodeAttributeChange = onNodeAttributeChange; + assert.ok(isAttributeChangeTracked, 'Attribute foo:from="bar" should be tracked'); + assert.equal(attributeChangeCount, 0, 'all attribute listeners should be disposed'); + domMutate.onNodeRemoval = onNodeRemoval; + assert.ok(isRemovalTracked, 'Element span should be tracked'); + assert.equal(removalCount, 0, 'all removal listeners should be disposed'); + done(); + }); + viewModel.attr('isShowing', false); + }); + QUnit.test('raw bindings using :raw', function (assert) { + var template = stache(''); + var frag = template(); + assert.equal(frag.firstChild.getAttribute('foo'), 'bar', 'bound raw'); + }); + testIfRealDocument('Bindings are removed when the node\'s documentElement is', function (assert) { + var done = assert.async(); + var realDoc = globals.getKeyValue('document'); + var d = doc.implementation.createHTMLDocument('Test'); + globals.setKeyValue('document', d); + var template = stache('
    Test
    '); + d.body.appendChild(template({ + doStuff: function () { + } + })); + var el = d.body.firstChild; + var removalDisposal = domMutate.onNodeRemoval(el, function () { + removalDisposal(); + globals.setKeyValue('document', realDoc); + assert.ok(true, 'Tore down bindings correctly'); + done(); + }); + d.removeChild(d.documentElement); + }); + }); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-stache-bindings@4.6.4#test/tests*/ +define('can-stache-bindings@4.6.4#test/tests', [ + 'require', + 'exports', + 'module', + './colon/tests', + './data/tests' +], function (require, exports, module) { + require('./colon/tests'); + require('./data/tests'); +}); +/*can-query-logic@1.1.6#src/set*/ +define('can-query-logic@1.1.6#src/set', [ + 'require', + 'exports', + 'module', + 'can-symbol', + 'can-reflect' +], function (require, exports, module) { + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + var set; + var addSerializeToThis = function (obj) { + return canReflect.assignSymbols(obj, { + 'can.serialize': function () { + return this; + } + }); + }; + function reverseArgs(fn) { + return function (first, second) { + return fn.call(this, second, first); + }; + } + var setComparisonsSymbol = canSymbol.for('can.setComparisons'); + function addComparators(type1, type2, comparators) { + var comparisons = type1[setComparisonsSymbol]; + if (!type1[setComparisonsSymbol]) { + comparisons = type1[setComparisonsSymbol] = new Map(); + } + var subMap = comparisons.get(type1); + if (!subMap) { + subMap = new Map(); + comparisons.set(type1, subMap); + } + var existingComparators = subMap.get(type2); + if (existingComparators) { + for (var prop in comparators) { + if (existingComparators.hasOwnProperty(prop)) { + console.warn('Overwriting ' + type1.name + ' ' + prop + ' ' + type2.name + ' comparitor'); + } + existingComparators[prop] = comparators[prop]; + } + } else { + subMap.set(type2, comparators); + } + } + function Identity() { + } + var typeMap = { + 'number': Identity, + 'string': Identity, + 'undefined': Identity, + 'boolean': Identity + }; + var get = {}; + [ + 'intersection', + 'difference', + 'union' + ].forEach(function (prop) { + get[prop] = function (forwardComparators, value1, value2) { + if (value2 === set.UNIVERSAL) { + if (prop === 'intersection') { + return value1; + } + if (prop === 'union') { + return set.UNIVERSAL; + } + if (prop === 'difference') { + return set.EMPTY; + } + } + if (value1 === set.UNIVERSAL) { + if (prop === 'intersection') { + return value1; + } + if (prop === 'union') { + return set.UNIVERSAL; + } + } + if (forwardComparators && forwardComparators[prop]) { + var result = forwardComparators[prop](value1, value2); + if (result === undefined && forwardComparators.undefinedIsEmptySet === true) { + return set.EMPTY; + } else { + return result; + } + } else { + throw new Error('Unable to perform ' + prop + ' between ' + set.getType(value1).name + ' and ' + set.getType(value2).name); + } + }; + }); + set = { + UNIVERSAL: canReflect.assignSymbols({ name: 'UNIVERSAL' }, { + 'can.serialize': function () { + return this; + }, + 'can.isMember': function () { + return true; + } + }), + EMPTY: canReflect.assignSymbols({ name: 'EMPTY' }, { + 'can.serialize': function () { + return this; + }, + 'can.isMember': function () { + return false; + } + }), + UNDEFINABLE: addSerializeToThis({ name: 'UNDEFINABLE' }), + UNKNOWABLE: addSerializeToThis({ name: 'UNKNOWABLE' }), + Identity: Identity, + isSpecial: function (setA) { + return setA === set.UNIVERSAL || setA === set.EMPTY || setA === set.UNDEFINABLE || setA === set.UNKNOWABLE; + }, + isDefinedAndHasMembers: function (setA) { + if (setA !== set.EMPTY && setA !== set.UNDEFINABLE && setA !== set.UNKNOWABLE) { + return setA; + } else { + return false; + } + }, + getType: function (value) { + if (value === set.UNIVERSAL) { + return set.UNIVERSAL; + } + if (value === set.EMPTY) { + return set.EMPTY; + } + if (value === set.UNKNOWABLE) { + return set.UNKNOWABLE; + } + if (value === null) { + return Identity; + } + if (typeMap.hasOwnProperty(typeof value)) { + return typeMap[typeof value]; + } + return value.constructor; + }, + ownAndMemberValue: function (startOwnValue, startMemberValue) { + if (startOwnValue != null || startMemberValue != null) { + var ownValue = startOwnValue != null ? startOwnValue.valueOf() : startOwnValue, memberValue = startMemberValue != null ? startMemberValue.valueOf() : startMemberValue; + if (startOwnValue == null || startMemberValue == null) { + return { + own: ownValue, + member: memberValue + }; + } + if (ownValue == null || ownValue.constructor !== memberValue.constructor) { + memberValue = new startOwnValue.constructor(memberValue).valueOf(); + } + return { + own: ownValue, + member: memberValue + }; + } + return { + own: startMemberValue, + member: startOwnValue + }; + }, + getComparisons: function (Type1, Type2) { + var comparisons = Type1[setComparisonsSymbol]; + if (comparisons) { + var subMap = comparisons.get(Type1); + if (subMap) { + return subMap.get(Type2); + } + } + }, + hasComparisons: function (Type) { + return !!Type[setComparisonsSymbol]; + }, + defineComparison: function (type1, type2, comparators) { + addComparators(type1, type2, comparators); + if (type1 !== type2) { + var reverse = {}; + for (var prop in comparators) { + if (prop !== 'difference') { + reverse[prop] = reverseArgs(comparators[prop]); + } + } + addComparators(type2, type1, reverse); + } + }, + isSubset: function (value1, value2) { + if (value1 === value2) { + return true; + } + var Type1 = set.getType(value1), Type2 = set.getType(value2); + var forwardComparators = set.getComparisons(Type1, Type2); + if (forwardComparators) { + var intersection = get.intersection(forwardComparators, value1, value2); + var difference = get.difference(forwardComparators, value1, value2); + if (intersection === set.UNKNOWABLE || difference === set.UNKNOWABLE) { + return undefined; + } else if (intersection !== set.EMPTY && difference === set.EMPTY) { + return true; + } else { + return false; + } + } else { + throw new Error('Unable to perform subset comparison between ' + Type1.name + ' and ' + Type2.name); + } + }, + isProperSubset: function (setA, setB) { + return set.isSubset(setA, setB) && !set.isEqual(setA, setB); + }, + isEqual: function (value1, value2) { + if (value1 === set.UNKNOWABLE || value2 === set.UNKNOWABLE) { + return set.UNKNOWABLE; + } + var isSpecial1 = set.isSpecial(value1), isSpecial2 = set.isSpecial(value2); + if (isSpecial1 && isSpecial2) { + return isSpecial1 === isSpecial2; + } + var Type1 = set.getType(value1), Type2 = set.getType(value2); + if (value1 === value2) { + return true; + } + var forwardComparators = set.getComparisons(Type1, Type2); + var reverseComparators = set.getComparisons(Type2, Type1); + if (forwardComparators && reverseComparators) { + var intersection = get.intersection(forwardComparators, value1, value2); + var difference = get.difference(forwardComparators, value1, value2); + if (intersection !== set.EMPTY && difference === set.EMPTY) { + var reverseIntersection = get.intersection(reverseComparators, value2, value1); + var reverseDifference = get.difference(reverseComparators, value2, value1); + return reverseIntersection !== set.EMPTY && reverseDifference === set.EMPTY; + } else { + return false; + } + } else { + var values = set.ownAndMemberValue(value1, value2); + if (canReflect.isPrimitive(values.own) && canReflect.isPrimitive(values.member)) { + return values.own === values.member; + } else { + throw new Error('Unable to perform equal comparison between ' + Type1.name + ' and ' + Type2.name); + } + } + }, + union: function (value1, value2) { + if (value1 === set.UNIVERSAL || value2 === set.UNIVERSAL) { + return set.UNIVERSAL; + } + if (value1 === set.EMPTY) { + return value2; + } else if (value2 === set.EMPTY) { + return value1; + } + if (value1 === set.UNKNOWABLE || value2 === set.UNKNOWABLE) { + return set.UNKNOWABLE; + } + var Type1 = set.getType(value1), Type2 = set.getType(value2); + var forwardComparators = set.getComparisons(Type1, Type2); + return get.union(forwardComparators, value1, value2); + }, + intersection: function (value1, value2) { + if (value1 === set.UNIVERSAL) { + return value2; + } + if (value2 === set.UNIVERSAL) { + return value1; + } + if (value1 === set.EMPTY || value2 === set.EMPTY) { + return set.EMPTY; + } + if (value1 === set.UNKNOWABLE || value2 === set.UNKNOWABLE) { + return set.UNKNOWABLE; + } + var Type1 = set.getType(value1), Type2 = set.getType(value2); + var forwardComparators = set.getComparisons(Type1, Type2); + if (forwardComparators) { + return get.intersection(forwardComparators, value1, value2); + } else { + throw new Error('Unable to perform intersection comparison between ' + Type1.name + ' and ' + Type2.name); + } + }, + difference: function (value1, value2) { + if (value1 === set.EMPTY) { + return set.EMPTY; + } + if (value2 === set.EMPTY) { + return value1; + } + if (value1 === set.UNKNOWABLE || value2 === set.UNKNOWABLE) { + return set.UNKNOWABLE; + } + var Type1 = set.getType(value1), Type2 = set.getType(value2); + var forwardComparators = set.getComparisons(Type1, Type2); + if (forwardComparators) { + return get.difference(forwardComparators, value1, value2); + } else { + throw new Error('Unable to perform difference comparison between ' + Type1.name + ' and ' + Type2.name); + } + }, + indexWithEqual: function (arr, value) { + for (var i = 0, len = arr.length; i < len; i++) { + if (set.isEqual(arr[i], value)) { + return i; + } + } + return -1; + } + }; + function identityIntersection(v1, v2) { + return v1 === v2 ? v1 : set.EMPTY; + } + function identityDifference(v1, v2) { + return v1 === v2 ? set.EMPTY : v1; + } + function identityUnion(v1, v2) { + return v1 === v2 ? v1 : set.UNDEFINABLE; + } + var identityComparitor = { + intersection: identityIntersection, + difference: identityDifference, + union: identityUnion + }; + set.defineComparison(Identity, Identity, identityComparitor); + set.defineComparison(set.UNIVERSAL, set.UNIVERSAL, identityComparitor); + module.exports = set; +}); +/*can-query-logic@1.1.6#src/set-test*/ +define('can-query-logic@1.1.6#src/set-test', [ + 'require', + 'exports', + 'module', + './set', + 'steal-qunit' +], function (require, exports, module) { + var set = require('./set'); + var QUnit = require('steal-qunit'); + QUnit.module('can-query-logic/set'); + QUnit.test('.ownAndMemberValue', function () { + QUnit.deepEqual(set.ownAndMemberValue(1, '1'), { + own: 1, + member: 1 + }, '1 and \'1\''); + QUnit.deepEqual(set.ownAndMemberValue({ + valueOf: function () { + return null; + } + }, '1'), { + own: null, + member: '1' + }, '{null} and \'1\''); + }); +}); +/*can-query-logic@1.1.6#src/array-union-intersection-difference*/ +define('can-query-logic@1.1.6#src/array-union-intersection-difference', [ + 'require', + 'exports', + 'module', + './set' +], function (require, exports, module) { + var SET = require('./set'); + function getValue(value) { + return value == null ? value : value.valueOf(); + } + module.exports = function arrayUnionIntersectionDifference(arr1, arr2) { + var set = new Set(); + var intersection = []; + var union = []; + var difference = arr1.slice(0); + arr1.forEach(function (value) { + set.add(getValue(value)); + union.push(value); + }); + arr2.forEach(function (value) { + if (set.has(getValue(value))) { + intersection.push(value); + var index = SET.indexWithEqual(difference, value); + if (index !== -1) { + difference.splice(index, 1); + } + } else { + union.push(value); + } + }); + return { + intersection: intersection, + union: union, + difference: difference + }; + }; +}); +/*can-query-logic@1.1.6#src/types/comparisons*/ +define('can-query-logic@1.1.6#src/types/comparisons', [ + 'require', + 'exports', + 'module', + '../set', + '../array-union-intersection-difference', + 'can-symbol' +], function (require, exports, module) { + var set = require('../set'); + var arrayUnionIntersectionDifference = require('../array-union-intersection-difference'); + var canSymbol = require('can-symbol'); + var isMemberSymbol = canSymbol.for('can.isMember'); + var comparisons = { + In: function In(values) { + this.values = values; + }, + NotIn: function NotIn(values) { + this.values = values; + }, + GreaterThan: function GreaterThan(value) { + this.value = value; + }, + GreaterThanEqual: function GreaterThanEqual(value) { + this.value = value; + }, + LessThan: function LessThan(value) { + this.value = value; + }, + LessThanEqual: function LessThanEqual(value) { + this.value = value; + }, + And: function ValueAnd(ands) { + this.values = ands; + }, + Or: function ValueOr(ors) { + this.values = ors; + } + }; + comparisons.Or.prototype.orValues = function () { + return this.values; + }; + comparisons.In.test = function (values, b) { + return values.some(function (value) { + var values = set.ownAndMemberValue(value, b); + return values.own === values.member; + }); + }; + comparisons.NotIn.test = function (values, b) { + return !comparisons.In.test(values, b); + }; + comparisons.NotIn.testValue = function (value, b) { + return !comparisons.In.testValue(value, b); + }; + function nullIsFalse(test) { + return function (arg1, arg2) { + if (arg1 == null || arg2 == null) { + return false; + } else { + return test(arg1, arg2); + } + }; + } + function nullIsFalseTwoIsOk(test) { + return function (arg1, arg2) { + if (arg1 === arg2) { + return true; + } else if (arg1 == null || arg2 == null) { + return false; + } else { + return test(arg1, arg2); + } + }; + } + comparisons.GreaterThan.test = nullIsFalse(function (a, b) { + return a > b; + }); + comparisons.GreaterThanEqual.test = nullIsFalseTwoIsOk(function (a, b) { + return a >= b; + }); + comparisons.LessThan.test = nullIsFalse(function (a, b) { + return a < b; + }); + comparisons.LessThanEqual.test = nullIsFalseTwoIsOk(function (a, b) { + return a <= b; + }); + function isMemberThatUsesTest(value) { + var values = set.ownAndMemberValue(this.value, value); + return this.constructor.test(values.member, values.own); + } + [ + comparisons.GreaterThan, + comparisons.GreaterThanEqual, + comparisons.LessThan, + comparisons.LessThanEqual, + comparisons.LessThan + ].forEach(function (Type) { + Type.prototype.isMember = isMemberThatUsesTest; + }); + function isMemberThatUsesTestOnValues(value) { + return this.constructor.test(this.values, value); + } + [ + comparisons.In, + comparisons.NotIn + ].forEach(function (Type) { + Type.prototype.isMember = isMemberThatUsesTestOnValues; + }); + comparisons.And.prototype.isMember = function (value) { + return this.values.every(function (and) { + return and.isMember(value); + }); + }; + comparisons.Or.prototype.isMember = function (value) { + return this.values.some(function (and) { + return and.isMember(value); + }); + }; + Object.keys(comparisons).forEach(function (name) { + comparisons[name].prototype[isMemberSymbol] = comparisons[name].prototype.isMember; + }); + function makeNot(Type) { + return { + test: function (vA, vB) { + return !Type.test(vA, vB); + } + }; + } + function makeEnum(type, Type, emptyResult) { + return function (a, b) { + var result = arrayUnionIntersectionDifference(a.values, b.values); + if (result[type].length) { + return new Type(result[type]); + } else { + return emptyResult || set.EMPTY; + } + }; + } + function isUniversal(aSet) { + return set.isEqual(set.UNIVERSAL, aSet); + } + function swapArgs(fn) { + return function (a, b) { + return fn(b, a); + }; + } + function makeSecondValue(Type, prop) { + return function (universe, value) { + return new Type(value[prop || 'value']); + }; + } + function returnBiggerValue(gtA, gtB) { + if (gtA.value < gtB.value) { + return gtB; + } else { + return gtA; + } + } + function returnSmallerValue(gtA, gtB) { + if (gtA.value > gtB.value) { + return gtB; + } else { + return gtA; + } + } + function makeAndIf(Comparison, Type) { + return function (ltA, ltB) { + if (Comparison.test(ltA.value, ltB.value)) { + return makeAnd([ + ltA, + new Type(ltB.value) + ]); + } else { + return set.EMPTY; + } + }; + } + function make_InIfEqual_else_andIf(Comparison, Type) { + var elseCase = makeAndIf(Comparison, Type); + return function (a, b) { + if (a.value === b.value) { + return new is.In([a.value]); + } else { + return elseCase(a, b); + } + }; + } + function make_filterFirstValueAgainstSecond(Comparison, Type, defaultReturn) { + return function (inSet, gt) { + var values = inSet.values.filter(function (value) { + return Comparison.test(gt, value); + }); + return values.length ? new Type(values) : defaultReturn || set.EMPTY; + }; + } + function make_filterFirstValues(Comparison, Type, defaultReturn) { + return function (inSet, gt) { + var values = inSet.values.filter(function (value) { + return Comparison.test(value, gt.value); + }); + return values.length ? new Type(values) : defaultReturn || set.EMPTY; + }; + } + var isMemberTest = { + test: function isMemberTest(set, value) { + return set.isMember(value); + } + }; + var returnTrue = { + test: function returnTrue() { + return true; + } + }; + var returnFalse = { + test: function returnFalse() { + return false; + } + }; + function isOr(value) { + return value instanceof is.Or; + } + function isAnd(value) { + return value instanceof is.And; + } + function isAndOrOr(value) { + return isAnd(value) || isOr(value); + } + function combineFilterFirstValues(options) { + return function (inSet, gt) { + var values = inSet.values.filter(function (value) { + return options.values.test(value, gt.value); + }); + var range = options.with ? new options.with(gt.value) : gt; + return values.length ? options.combinedUsing([ + new options.arePut(values), + range + ]) : range; + }; + } + function combineFilterFirstValuesAgainstSecond(options) { + return function (inSet, gt) { + var values = inSet.values.filter(function (value) { + return options.values.test(gt, value); + }); + var range; + if (options.complement) { + range = set.difference(set.UNIVERSAL, gt); + } else if (options.with) { + range = new options.with(gt.value); + } else { + range = gt; + } + return values.length ? options.combinedUsing([ + new options.arePut(values), + range + ]) : range; + }; + } + function makeOrUnless(Comparison, result) { + return function (setA, setB) { + if (Comparison.test(setA.value, setB.value)) { + return result || set.UNIVERSAL; + } else { + return makeOr([ + setA, + setB + ]); + } + }; + } + function makeAndUnless(Comparison, result) { + return function (setA, setB) { + if (Comparison.test(setA.value, setB.value)) { + return result || set.EMPTY; + } else { + return makeAnd([ + setA, + setB + ]); + } + }; + } + function makeComplementSecondArgIf(Comparison) { + return function (setA, setB) { + if (Comparison.test(setA.value, setB.value)) { + return set.difference(set.UNIVERSAL, setB); + } else { + return setA; + } + }; + } + function makeAnd(ands) { + return comparisons.And ? new comparisons.And(ands) : set.UNDEFINABLE; + } + function makeOr(ors) { + return comparisons.Or ? new comparisons.Or(ors) : set.UNDEFINABLE; + } + var is = comparisons; + function combineValueWithRangeCheck(inSet, rangeSet, RangeOrEqType) { + var gte = new RangeOrEqType(rangeSet.value); + var leftValues = inSet.values.filter(function (value) { + return !gte.isMember(value); + }); + if (!leftValues.length) { + return gte; + } + if (leftValues.length < inSet.values.length) { + return makeOr([ + new is.In(leftValues), + gte + ]); + } else { + return makeOr([ + inSet, + rangeSet + ]); + } + } + function makeOrWithInAndRange(inSet, rangeSet) { + if (rangeSet instanceof is.Or) { + var firstResult = makeOrWithInAndRange(inSet, rangeSet.values[0]); + if (!(firstResult instanceof is.Or)) { + return set.union(firstResult, rangeSet.values[1]); + } + var secondResult = makeOrWithInAndRange(inSet, rangeSet.values[1]); + if (!(secondResult instanceof is.Or)) { + return set.union(secondResult, rangeSet.values[0]); + } + return makeOr([ + inSet, + rangeSet + ]); + } else { + if (rangeSet instanceof is.GreaterThan) { + return combineValueWithRangeCheck(inSet, rangeSet, is.GreaterThanEqual); + } + if (rangeSet instanceof is.LessThan) { + return combineValueWithRangeCheck(inSet, rangeSet, is.LessThanEqual); + } + return makeOr([ + inSet, + rangeSet + ]); + } + } + var In_RANGE = { + union: combineFilterFirstValuesAgainstSecond({ + values: makeNot(isMemberTest), + arePut: is.In, + combinedUsing: function (ors) { + return makeOrWithInAndRange(ors[0], ors[1]); + } + }), + intersection: make_filterFirstValueAgainstSecond(isMemberTest, is.In, set.EMPTY), + difference: make_filterFirstValueAgainstSecond(makeNot(isMemberTest), is.In, set.EMPTY) + }; + var RANGE_IN = { + difference: swapArgs(combineFilterFirstValuesAgainstSecond({ + values: isMemberTest, + arePut: is.NotIn, + combinedUsing: makeAnd + })) + }; + var NotIn_RANGE = function () { + return { + union: make_filterFirstValueAgainstSecond(makeNot(isMemberTest), is.NotIn, set.UNIVERSAL), + intersection: combineFilterFirstValuesAgainstSecond({ + values: isMemberTest, + arePut: is.NotIn, + combinedUsing: makeAnd + }), + difference: combineFilterFirstValuesAgainstSecond({ + values: makeNot(isMemberTest), + arePut: is.NotIn, + combinedUsing: makeAnd, + complement: true + }) + }; + }; + var RANGE_NotIn = { difference: swapArgs(make_filterFirstValueAgainstSecond(isMemberTest, is.In, set.EMPTY)) }; + var RANGE_And_Union = function (gt, and) { + var union1 = set.union(gt, and.values[0]); + var union2 = set.union(gt, and.values[1]); + if (!isAndOrOr(union1) && !isAndOrOr(union2)) { + return set.intersection(union1, union2); + } else { + return new is.Or([ + gt, + and + ]); + } + }; + var RANGE_And_Intersection = function (gt, and) { + var and1 = and.values[0], and2 = and.values[1]; + var intersection1 = set.intersection(gt, and1); + var intersection2 = set.intersection(gt, and2); + if (intersection1 === set.EMPTY || intersection2 === set.EMPTY) { + return set.EMPTY; + } + if (!isAndOrOr(intersection1)) { + return new set.intersection(intersection1, and2); + } + if (!isAndOrOr(intersection2)) { + return new set.intersection(intersection2, and1); + } else { + return new is.And([ + gt, + and + ]); + } + }; + var RANGE_And_Difference = function (gt, and) { + var and1 = and.values[0], and2 = and.values[1]; + var difference1 = set.difference(gt, and1); + var difference2 = set.difference(gt, and2); + if (difference1 === set.EMPTY) { + return difference2; + } + if (difference2 === set.EMPTY) { + return difference1; + } + return new is.Or([ + difference1, + difference2 + ]); + }; + var And_RANGE_Difference = function (and, gt) { + var and1 = and.values[0], and2 = and.values[1]; + var difference1 = set.difference(and1, gt); + var difference2 = set.difference(and2, gt); + return set.intersection(difference1, difference2); + }; + var RANGE_Or = { + union: function (gt, or) { + var or1 = or.values[0], or2 = or.values[1]; + var union1 = set.union(gt, or1); + if (!isAndOrOr(union1)) { + return set.union(union1, or2); + } + var union2 = set.union(gt, or2); + if (!isAndOrOr(union2)) { + return set.union(or1, union2); + } else { + return new is.Or([ + gt, + or + ]); + } + }, + intersection: function (gt, or) { + var or1 = or.values[0], or2 = or.values[1]; + var intersection1 = set.intersection(gt, or1); + var intersection2 = set.intersection(gt, or2); + if (intersection1 === set.EMPTY) { + return intersection2; + } + if (intersection2 === set.EMPTY) { + return intersection1; + } + return set.union(intersection1, intersection2); + }, + difference: function (gt, or) { + var or1 = or.values[0], or2 = or.values[1]; + var difference1 = set.difference(gt, or1); + var difference2 = set.difference(gt, or2); + return set.intersection(difference1, difference2); + } + }; + var Or_RANGE = { + difference: function (or, gt) { + var or1 = or.values[0], or2 = or.values[1]; + var difference1 = set.difference(or1, gt); + var difference2 = set.difference(or2, gt); + return set.union(difference1, difference2); + } + }; + var comparators = { + In_In: { + union: makeEnum('union', is.In), + intersection: makeEnum('intersection', is.In), + difference: makeEnum('difference', is.In) + }, + UNIVERSAL_In: { difference: makeSecondValue(is.NotIn, 'values') }, + In_NotIn: { + union: swapArgs(makeEnum('difference', is.NotIn, set.UNIVERSAL)), + intersection: makeEnum('difference', is.In), + difference: makeEnum('intersection', is.In) + }, + NotIn_In: { difference: makeEnum('union', is.NotIn) }, + In_GreaterThan: In_RANGE, + GreaterThan_In: RANGE_IN, + In_GreaterThanEqual: In_RANGE, + GreaterThanEqual_In: RANGE_IN, + In_LessThan: In_RANGE, + LessThan_In: RANGE_IN, + In_LessThanEqual: In_RANGE, + LessThanEqual_In: RANGE_IN, + In_And: In_RANGE, + And_In: RANGE_IN, + In_Or: In_RANGE, + Or_In: RANGE_IN, + NotIn_NotIn: { + union: makeEnum('intersection', is.NotIn, set.UNIVERSAL), + intersection: makeEnum('union', is.NotIn), + difference: makeEnum('difference', is.In) + }, + UNIVERSAL_NotIn: { difference: makeSecondValue(is.In, 'values') }, + NotIn_GreaterThan: NotIn_RANGE(), + GreaterThan_NotIn: RANGE_NotIn, + NotIn_GreaterThanEqual: NotIn_RANGE(), + GreaterThanEqual_NotIn: RANGE_NotIn, + NotIn_LessThan: NotIn_RANGE(), + LessThan_NotIn: RANGE_NotIn, + NotIn_LessThanEqual: NotIn_RANGE(), + LessThanEqual_NotIn: RANGE_NotIn, + NotIn_And: NotIn_RANGE(), + And_NotIn: RANGE_NotIn, + NotIn_Or: NotIn_RANGE(), + Or_NotIn: RANGE_NotIn, + GreaterThan_GreaterThan: { + union: returnSmallerValue, + intersection: returnBiggerValue, + difference: makeAndIf(is.LessThan, is.LessThanEqual) + }, + UNIVERSAL_GreaterThan: { difference: makeSecondValue(is.LessThanEqual) }, + GreaterThan_GreaterThanEqual: { + union: returnSmallerValue, + intersection: returnBiggerValue, + difference: makeAndIf(is.LessThan, is.LessThan) + }, + GreaterThanEqual_GreaterThan: { difference: make_InIfEqual_else_andIf(is.LessThan, is.LessThanEqual) }, + GreaterThan_LessThan: { + union: function () { + var makeOrUnlessLessThan = makeOrUnless(is.LessThan); + return function greaterThan_lessThan_union(a, b) { + if (comparisons.In.test([a.value], b.value)) { + return new is.NotIn([a.value]); + } else { + return makeOrUnlessLessThan(a, b); + } + }; + }(), + intersection: makeAndUnless(is.GreaterThan), + difference: makeComplementSecondArgIf(is.LessThan) + }, + LessThan_GreaterThan: { difference: makeComplementSecondArgIf(is.GreaterThan) }, + GreaterThan_LessThanEqual: { + union: makeOrUnless(is.LessThanEqual), + intersection: makeAndUnless(is.GreaterThanEqual), + difference: makeComplementSecondArgIf(is.LessThanEqual) + }, + LessThanEqual_GreaterThan: { difference: makeComplementSecondArgIf(is.GreaterThanEqual) }, + GreaterThan_And: { + union: RANGE_And_Union, + intersection: RANGE_And_Intersection, + difference: RANGE_And_Difference + }, + And_GreaterThan: { difference: And_RANGE_Difference }, + GreaterThan_Or: RANGE_Or, + Or_GreaterThan: Or_RANGE, + GreaterThanEqual_GreaterThanEqual: { + union: returnSmallerValue, + intersection: returnBiggerValue, + difference: makeAndIf(is.LessThan, is.LessThan) + }, + UNIVERSAL_GreaterThanEqual: { difference: makeSecondValue(is.LessThan) }, + GreaterThanEqual_LessThan: { + union: makeOrUnless(is.LessThanEqual), + intersection: makeAndUnless(is.GreaterThanEqual), + difference: makeComplementSecondArgIf(is.LessThanEqual) + }, + LessThan_GreaterThanEqual: { difference: makeComplementSecondArgIf(is.GreaterThanEqual) }, + GreaterThanEqual_LessThanEqual: { + union: makeOrUnless(is.LessThanEqual), + intersection: function () { + var makeAnd = makeAndUnless(is.GreaterThan); + return function gte_lte_intersection(gte, lte) { + var inSet = new is.In([gte.value]); + if (inSet.isMember(lte.value)) { + return inSet; + } else { + return makeAnd(gte, lte); + } + }; + }(), + difference: makeComplementSecondArgIf(is.LessThanEqual) + }, + LessThanEqual_GreaterThanEqual: { difference: makeComplementSecondArgIf(is.GreaterThanEqual) }, + GreaterThanEqual_And: { + union: RANGE_And_Union, + intersection: RANGE_And_Intersection, + difference: RANGE_And_Difference + }, + And_GreaterThanEqual: { difference: And_RANGE_Difference }, + GreaterThanEqual_Or: RANGE_Or, + Or_GreaterThanEqual: Or_RANGE, + LessThan_LessThan: { + union: returnBiggerValue, + intersection: returnSmallerValue, + difference: makeAndIf(is.GreaterThan, is.GreaterThanEqual) + }, + UNIVERSAL_LessThan: { difference: makeSecondValue(is.GreaterThanEqual) }, + LessThan_LessThanEqual: { + union: returnBiggerValue, + intersection: returnSmallerValue, + difference: makeAndIf(is.GreaterThan, is.GreaterThan) + }, + LessThanEqual_LessThan: { difference: make_InIfEqual_else_andIf(is.GreaterThanEqual, is.GreaterThanEqual) }, + LessThan_And: { + union: RANGE_And_Union, + intersection: RANGE_And_Intersection, + difference: RANGE_And_Difference + }, + And_LessThan: { difference: And_RANGE_Difference }, + LessThan_Or: RANGE_Or, + Or_LessThan: Or_RANGE, + LessThanEqual_LessThanEqual: { + union: returnBiggerValue, + intersection: returnSmallerValue, + difference: function (lteA, lteB) { + if (lteA.value >= lteB.value) { + return makeAnd([ + lteA, + new is.GreaterThan(lteB.value) + ]); + } else { + return set.EMPTY; + } + } + }, + UNIVERSAL_LessThanEqual: { difference: makeSecondValue(is.GreaterThan) }, + LessThanEqual_And: { + union: RANGE_And_Union, + intersection: RANGE_And_Intersection, + difference: RANGE_And_Difference + }, + And_LessThanEqual: { difference: And_RANGE_Difference }, + LessThanEqual_Or: RANGE_Or, + Or_LessThanEqual: Or_RANGE, + And_And: { + union: function (and1, and2) { + var union1 = set.union(and1, and2.values[0]); + var union2 = set.union(and1, and2.values[1]); + if (isAndOrOr(union1) || isAndOrOr(union2)) { + union1 = set.union(and2, and1.values[0]); + union2 = set.union(and2, and1.values[1]); + } + if (isAndOrOr(union1) || isAndOrOr(union2)) { + return new is.Or([ + and1, + and2 + ]); + } else { + return set.intersection(union1, union2); + } + }, + intersection: function (and1, and2) { + var intersection1 = set.intersection(and1.values[0], and2.values[0]); + var intersection2 = set.intersection(and1.values[1], and2.values[1]); + if (!isAndOrOr(intersection1) || !isAndOrOr(intersection2)) { + return set.intersection(intersection1, intersection2); + } + intersection1 = set.intersection(and1.values[0], and2.values[1]); + intersection2 = set.intersection(and1.values[1], and2.values[0]); + if (!isAndOrOr(intersection1) || !isAndOrOr(intersection2)) { + return set.intersection(intersection1, intersection2); + } else { + return new is.And([ + and1, + and2 + ]); + } + }, + difference: function () { + return function (and1, and2) { + var d1 = set.difference(and1, and2.values[0]); + var d2 = set.difference(and1, and2.values[1]); + return set.union(d1, d2); + }; + }() + }, + And_Or: { + union: function (and, or) { + var aUnion = set.union(and.values[0], or); + var bUnion = set.union(and.values[1], or); + if (!isAndOrOr(aUnion) || !isAndOrOr(bUnion)) { + return set.intersection(aUnion, bUnion); + } + return new is.Or([ + and, + or + ]); + }, + intersection: function (and, or) { + var aIntersection = set.intersection(and, or.values[0]); + var bIntersection = set.intersection(and, or.values[1]); + if (!isOr(aIntersection) && !isOr(bIntersection)) { + return set.union(aIntersection, bIntersection); + } + return new is.And([ + and, + or + ]); + }, + difference: function (and, or) { + var aDiff = set.difference(and, or.values[0]); + var bDiff = set.difference(and, or.values[1]); + return set.intersection(aDiff, bDiff); + } + }, + Or_And: { + difference: function (or, and) { + var aDiff = set.difference(or, and.values[0]); + var bDiff = set.difference(or, and.values[1]); + return set.union(aDiff, bDiff); + } + }, + UNIVERSAL_And: { + difference: function (universe, and) { + var inverseFirst = set.difference(universe, and.values[0]), inverseSecond = set.difference(universe, and.values[1]); + return set.union(inverseFirst, inverseSecond); + } + }, + Or_Or: { + union: function (or1, or2) { + var union1 = set.union(or1.values[0], or2.values[0]); + var union2 = set.union(or1.values[1], or2.values[1]); + if (!isAndOrOr(union1) || !isAndOrOr(union2)) { + return set.union(union1, union2); + } + union1 = set.union(or1.values[0], or2.values[1]); + union2 = set.union(or1.values[1], or2.values[0]); + if (!isAndOrOr(union1) || !isAndOrOr(union2)) { + return set.union(union1, union2); + } else { + return new is.Or([ + or1, + or2 + ]); + } + }, + intersection: function (or1, or2) { + var c = or2.values[0], d = or2.values[1]; + var intersection1 = set.intersection(or1, c); + var intersection2 = set.intersection(or1, d); + if (!isOr(intersection1) || !isOr(intersection2)) { + return set.union(intersection1, intersection2); + } + intersection1 = set.union(or2, or1.values[0]); + intersection2 = set.union(or2, or1.values[1]); + if (!isOr(intersection1) || !isOr(intersection2)) { + return set.union(intersection1, intersection2); + } else { + return new is.Or([ + or1, + or2 + ]); + } + }, + difference: function (or1, or2) { + var d1 = set.difference(or1, or2.values[0]); + var d2 = set.difference(or1, or2.values[1]); + return set.intersection(d1, d2); + } + }, + UNIVERSAL_Or: { + difference: function (universe, or) { + var inverseFirst = set.difference(universe, or.values[0]), inverseSecond = set.difference(universe, or.values[1]); + return set.intersection(inverseFirst, inverseSecond); + } + } + }; + var names = Object.keys(comparisons); + names.forEach(function (name1, i) { + if (!comparators[name1 + '_' + name1]) { + console.warn('no ' + name1 + '_' + name1); + } else { + set.defineComparison(comparisons[name1], comparisons[name1], comparators[name1 + '_' + name1]); + } + if (!comparators['UNIVERSAL_' + name1]) { + console.warn('no UNIVERSAL_' + name1); + } else { + set.defineComparison(set.UNIVERSAL, comparisons[name1], comparators['UNIVERSAL_' + name1]); + } + for (var j = i + 1; j < names.length; j++) { + var name2 = names[j]; + if (!comparators[name1 + '_' + name2]) { + console.warn('no ' + name1 + '_' + name2); + } else { + set.defineComparison(comparisons[name1], comparisons[name2], comparators[name1 + '_' + name2]); + } + if (!comparators[name2 + '_' + name1]) { + console.warn('no ' + name2 + '_' + name1); + } else { + set.defineComparison(comparisons[name2], comparisons[name1], comparators[name2 + '_' + name1]); + } + } + }); + module.exports = comparisons; +}); +/*can-query-logic@1.1.6#src/types/make-real-number-range-inclusive*/ +define('can-query-logic@1.1.6#src/types/make-real-number-range-inclusive', [ + 'require', + 'exports', + 'module', + '../set', + './comparisons' +], function (require, exports, module) { + var set = require('../set'); + var is = require('./comparisons'); + module.exports = function (min, max) { + function RealNumberRangeInclusive(start, end) { + this.start = arguments.length > 0 ? +start : min; + this.end = arguments.length > 1 ? +end : max; + this.range = new is.And([ + new is.GreaterThanEqual(this.start), + new is.LessThanEqual(this.end) + ]); + } + var universeRange = new RealNumberRangeInclusive(min, max); + function isUniversal(range) { + return set.isSubset(universeRange.range, range.range); + } + function rangeFromAnd(aSet) { + var values = {}; + aSet.values.forEach(function (value) { + if (value instanceof is.GreaterThanEqual) { + values.start = value.value; + } + if (value instanceof is.GreaterThan) { + values.start = value.value + 1; + } + if (value instanceof is.LessThanEqual) { + values.end = value.value; + } + if (value instanceof is.LessThan) { + values.end = value.value - 1; + } + }); + if ('start' in values && 'end' in values) { + return new RealNumberRangeInclusive(values.start, values.end); + } + } + function toRange(aSet) { + var range; + if (aSet instanceof is.And) { + range = rangeFromAnd(aSet); + } + if (aSet instanceof is.Or) { + var first = rangeFromAnd(aSet.values[0]), second = rangeFromAnd(aSet.values[1]); + if (first && second) { + var firstValues = first.range.values, secondValues = second.range.values; + if (firstValues[1].value + 1 === secondValues[0].value) { + range = new RealNumberRangeInclusive(firstValues[0].value, secondValues[1].value); + } else if (secondValues[1].value + 1 === firstValues[0].value) { + range = new RealNumberRangeInclusive(secondValues[0].value, firstValues[1].value); + } else { + return set.UNDEFINABLE; + } + } else { + return set.UNDEFINABLE; + } + } + if (range && isUniversal(range)) { + return set.UNIVERSAL; + } else { + return range; + } + } + function intersection(range1, range2) { + var intersection = toRange(set.intersection(range1.range, range2.range)); + if (intersection) { + return intersection; + } else { + return set.EMPTY; + } + } + function difference(range1, range2) { + var difference = toRange(set.difference(range1.range, range2.range)); + if (difference) { + return difference; + } else { + return set.EMPTY; + } + } + set.defineComparison(RealNumberRangeInclusive, RealNumberRangeInclusive, { + union: function (range1, range2) { + var union = toRange(set.union(range1.range, range2.range)); + if (union) { + return union; + } else { + return set.EMPTY; + } + }, + intersection: intersection, + difference: difference + }); + set.defineComparison(set.UNIVERSAL, RealNumberRangeInclusive, { + difference: function (universe, range) { + if (isUniversal(range)) { + return set.EMPTY; + } else { + return difference(universeRange, range); + } + } + }); + return RealNumberRangeInclusive; + }; +}); +/*can-query-logic@1.1.6#src/types/make-real-number-range-inclusive-test*/ +define('can-query-logic@1.1.6#src/types/make-real-number-range-inclusive-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + '../set', + './make-real-number-range-inclusive' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var set = require('../set'); + var RealNumberRangeInclusive = require('./make-real-number-range-inclusive')(-Infinity, Infinity); + QUnit.module('can-query-logic/types/make-real-number-range-inclusive'); + QUnit.test('isSubset', function () { + QUnit.equal(set.isSubset(new RealNumberRangeInclusive(1, 4), new RealNumberRangeInclusive(0, 5)), true, '1-4 subset of 0-5'); + QUnit.equal(set.isSubset(new RealNumberRangeInclusive(0, 5), new RealNumberRangeInclusive(1, 4)), false, '0-5 subset of 1-4 subset'); + }); + QUnit.test('isEqual with universal', function () { + QUnit.equal(set.isEqual(new RealNumberRangeInclusive(1, 4), set.UNIVERSAL), false, 'universal second'); + QUnit.equal(set.isEqual(set.UNIVERSAL, new RealNumberRangeInclusive(1, 4)), false, 'universal first'); + QUnit.equal(set.isEqual(new RealNumberRangeInclusive(-Infinity, Infinity), set.UNIVERSAL), true, 'eq universal second'); + QUnit.equal(set.isEqual(set.UNIVERSAL, new RealNumberRangeInclusive(-Infinity, Infinity)), true, 'eq universal second'); + }); +}); +/*can-query-logic@1.1.6#src/types/comparisons-test*/ +define('can-query-logic@1.1.6#src/types/comparisons-test', [ + 'require', + 'exports', + 'module', + './comparisons', + '../set' +], function (require, exports, module) { + var compare = require('./comparisons'); + var set = require('../set'); + var is = compare; + QUnit.module('can-query-logic/types/comparisons'); + var tests = { + In_In: { + union: function (assert) { + var isIn5 = new is.In([5]), isIn6 = new is.In([6]); + assert.deepEqual(set.union(isIn5, isIn6), new is.In([ + 5, + 6 + ])); + }, + intersection: function (assert) { + var isIn5 = new is.In([5]), isIn6 = new is.In([6]); + assert.deepEqual(set.intersection(isIn5, isIn6), set.EMPTY); + var in13 = new is.In([ + 1, + 2, + 3 + ]), in24 = new is.In([ + 2, + 3, + 4 + ]); + assert.deepEqual(set.intersection(in13, in24), new is.In([ + 2, + 3 + ])); + }, + difference: function (assert) { + var isIn5 = new is.In([5]), isIn6 = new is.In([6]); + assert.deepEqual(set.difference(isIn5, isIn6), isIn5); + var in13 = new is.In([ + 1, + 2, + 3 + ]), in24 = new is.In([ + 2, + 3, + 4 + ]); + assert.deepEqual(set.difference(in13, in24), new is.In([1])); + } + }, + In_isMember: function (assert) { + assert.ok(new is.In([5]).isMember(5)); + assert.notOk(new is.In([5]).isMember(6)); + assert.ok(new is.In([ + 5, + -1 + ]).isMember(-1)); + }, + UNIVERSAL_In: { + difference: function (assert) { + var isIn5 = new is.In([5]); + assert.deepEqual(set.difference(set.UNIVERSAL, isIn5), new is.NotIn([5])); + var in13 = new is.In([ + 1, + 2, + 3 + ]); + assert.deepEqual(set.difference(set.UNIVERSAL, in13), new is.NotIn([ + 1, + 2, + 3 + ])); + } + }, + In_NotIn: { + union: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.NotIn([ + 6, + 7 + ]); + assert.deepEqual(set.union(a, b), new is.NotIn([7])); + a = new is.In([ + 5, + 6 + ]); + b = new is.NotIn([ + 5, + 6 + ]); + assert.deepEqual(set.union(a, b), set.UNIVERSAL); + }, + intersection: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.NotIn([ + 6, + 7 + ]); + assert.deepEqual(set.intersection(a, b), new is.In([5])); + a = new is.In([ + 5, + 6 + ]); + b = new is.NotIn([ + 5, + 6 + ]); + assert.deepEqual(set.intersection(a, b), set.EMPTY); + }, + difference: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.NotIn([ + 6, + 7 + ]); + assert.deepEqual(set.difference(a, b), new is.In([6])); + a = new is.In([ + 5, + 6 + ]); + b = new is.NotIn([ + 5, + 6 + ]); + assert.deepEqual(set.difference(a, b), new is.In([ + 5, + 6 + ])); + a = new is.In([ + 5, + 6 + ]); + b = new is.NotIn([ + 8, + 9 + ]); + assert.deepEqual(set.difference(a, b), set.EMPTY); + } + }, + NotIn_In: { + difference: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.NotIn([ + 6, + 7 + ]); + assert.deepEqual(set.difference(b, a), new is.NotIn([ + 6, + 7, + 5 + ])); + a = new is.In([ + 5, + 6 + ]); + b = new is.NotIn([ + 5, + 6 + ]); + assert.deepEqual(set.difference(b, a), new is.NotIn([ + 5, + 6 + ])); + } + }, + In_GreaterThan: { + union: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.GreaterThan(3); + assert.deepEqual(set.union(a, b), b); + a = new is.In([ + 2, + 4 + ]); + b = new is.GreaterThan(3); + assert.deepEqual(set.union(a, b), new is.Or([ + new is.In([2]), + b + ])); + a = new is.In([ + 2, + 4 + ]); + b = new is.GreaterThan(2); + assert.deepEqual(set.union(a, b), new is.GreaterThanEqual(2)); + }, + intersection: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.GreaterThan(3); + assert.deepEqual(set.intersection(a, b), a); + a = new is.In([ + 2, + 4 + ]); + b = new is.GreaterThan(3); + assert.deepEqual(set.intersection(a, b), new is.In([4])); + a = new is.In([ + 2, + 4 + ]); + b = new is.GreaterThan(8); + assert.deepEqual(set.intersection(a, b), set.EMPTY); + }, + difference: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.GreaterThan(3); + assert.deepEqual(set.difference(a, b), set.EMPTY); + a = new is.In([ + 2, + 4 + ]); + b = new is.GreaterThan(3); + assert.deepEqual(set.difference(a, b), new is.In([2])); + a = new is.In([ + 2, + 4 + ]); + b = new is.GreaterThan(8); + assert.deepEqual(set.difference(a, b), new is.In([ + 2, + 4 + ])); + a = new is.In([ + null, + undefined + ]); + b = new is.GreaterThan(8); + assert.deepEqual(set.difference(a, b), new is.In([ + null, + undefined + ]), 'handles weird types'); + } + }, + GreaterThan_In: { + difference: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.GreaterThan(3); + var difference = set.difference(b, a); + assert.deepEqual(difference, new is.And([ + new is.NotIn([ + 5, + 6 + ]), + b + ])); + a = new is.In([ + 2, + 4 + ]); + b = new is.GreaterThan(3); + assert.deepEqual(set.difference(b, a), new is.And([ + new is.NotIn([4]), + b + ])); + a = new is.In([ + 2, + 4 + ]); + b = new is.GreaterThan(8); + assert.deepEqual(set.difference(b, a), b); + } + }, + In_GreaterThanEqual: { + union: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.GreaterThanEqual(3); + assert.deepEqual(set.union(a, b), b); + a = new is.In([ + 2, + 4 + ]); + b = new is.GreaterThanEqual(3); + assert.deepEqual(set.union(a, b), new is.Or([ + new is.In([2]), + b + ])); + a = new is.In([ + 2, + 4 + ]); + b = new is.GreaterThanEqual(2); + assert.deepEqual(set.union(a, b), b); + }, + intersection: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.GreaterThanEqual(3); + assert.deepEqual(set.intersection(a, b), a); + a = new is.In([ + 2, + 4 + ]); + b = new is.GreaterThanEqual(3); + assert.deepEqual(set.intersection(a, b), new is.In([4])); + a = new is.In([ + 2, + 4 + ]); + b = new is.GreaterThanEqual(8); + assert.deepEqual(set.intersection(a, b), set.EMPTY); + }, + difference: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.GreaterThanEqual(3); + assert.deepEqual(set.difference(a, b), set.EMPTY); + a = new is.In([ + 2, + 4 + ]); + b = new is.GreaterThanEqual(3); + assert.deepEqual(set.difference(a, b), new is.In([2])); + a = new is.In([ + 2, + 4 + ]); + b = new is.GreaterThanEqual(8); + assert.deepEqual(set.difference(a, b), new is.In([ + 2, + 4 + ])); + a = new is.In([ + 2, + 4 + ]); + b = new is.GreaterThanEqual(2); + assert.deepEqual(set.difference(a, b), set.EMPTY); + } + }, + GreaterThanEqual_In: { + difference: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.GreaterThanEqual(3); + var difference = set.difference(b, a); + assert.deepEqual(difference, new is.And([ + new is.NotIn([ + 5, + 6 + ]), + b + ])); + a = new is.In([ + 2, + 4 + ]); + b = new is.GreaterThanEqual(3); + assert.deepEqual(set.difference(b, a), new is.And([ + new is.NotIn([4]), + b + ])); + a = new is.In([ + 2, + 4 + ]); + b = new is.GreaterThanEqual(8); + assert.deepEqual(set.difference(b, a), b); + } + }, + In_LessThan: { + union: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.LessThan(7); + assert.deepEqual(set.union(a, b), b); + a = new is.In([ + 2, + 4 + ]); + b = new is.LessThan(3); + assert.deepEqual(set.union(a, b), new is.Or([ + new is.In([4]), + b + ])); + a = new is.In([ + 2, + 4 + ]); + b = new is.LessThan(4); + assert.deepEqual(set.union(a, b), new is.LessThanEqual(4)); + }, + intersection: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.LessThan(7); + assert.deepEqual(set.intersection(a, b), a); + a = new is.In([ + 2, + 4 + ]); + b = new is.LessThan(3); + assert.deepEqual(set.intersection(a, b), new is.In([2])); + a = new is.In([ + 2, + 4 + ]); + b = new is.LessThan(1); + assert.deepEqual(set.intersection(a, b), set.EMPTY); + }, + difference: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.LessThan(7); + assert.deepEqual(set.difference(a, b), set.EMPTY); + a = new is.In([ + 5, + 6 + ]); + b = new is.LessThan(6); + assert.deepEqual(set.difference(a, b), new is.In([6])); + a = new is.In([ + 2, + 4 + ]); + b = new is.LessThan(3); + assert.deepEqual(set.difference(a, b), new is.In([4])); + a = new is.In([ + 2, + 4 + ]); + b = new is.LessThan(1); + assert.deepEqual(set.difference(a, b), new is.In([ + 2, + 4 + ])); + } + }, + LessThan_In: { + difference: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.LessThan(7); + var difference = set.difference(b, a); + assert.deepEqual(difference, new is.And([ + new is.NotIn([ + 5, + 6 + ]), + b + ])); + a = new is.In([ + 2, + 4 + ]); + b = new is.LessThan(3); + assert.deepEqual(set.difference(b, a), new is.And([ + new is.NotIn([2]), + b + ])); + a = new is.In([ + 2, + 4 + ]); + b = new is.LessThan(1); + assert.deepEqual(set.difference(b, a), b); + } + }, + In_LessThanEqual: { + union: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.LessThanEqual(7); + assert.deepEqual(set.union(a, b), b); + a = new is.In([ + 2, + 4 + ]); + b = new is.LessThanEqual(3); + assert.deepEqual(set.union(a, b), new is.Or([ + new is.In([4]), + b + ])); + a = new is.In([ + 2, + 4 + ]); + b = new is.LessThanEqual(4); + assert.deepEqual(set.union(a, b), b); + }, + intersection: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.LessThanEqual(7); + assert.deepEqual(set.intersection(a, b), a); + a = new is.In([ + 2, + 4 + ]); + b = new is.LessThanEqual(3); + assert.deepEqual(set.intersection(a, b), new is.In([2])); + a = new is.In([ + 2, + 4 + ]); + b = new is.LessThanEqual(1); + assert.deepEqual(set.intersection(a, b), set.EMPTY); + }, + difference: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.LessThanEqual(7); + assert.deepEqual(set.difference(a, b), set.EMPTY); + a = new is.In([ + 5, + 6 + ]); + b = new is.LessThanEqual(6); + assert.deepEqual(set.difference(a, b), set.EMPTY); + a = new is.In([ + 2, + 4 + ]); + b = new is.LessThanEqual(3); + assert.deepEqual(set.difference(a, b), new is.In([4])); + a = new is.In([ + 2, + 4 + ]); + b = new is.LessThanEqual(1); + assert.deepEqual(set.difference(a, b), new is.In([ + 2, + 4 + ])); + } + }, + LessThanEqual_In: { + difference: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.LessThanEqual(7); + var difference = set.difference(b, a); + assert.deepEqual(difference, new is.And([ + new is.NotIn([ + 5, + 6 + ]), + b + ])); + a = new is.In([ + 2, + 4 + ]); + b = new is.LessThanEqual(3); + assert.deepEqual(set.difference(b, a), new is.And([ + new is.NotIn([2]), + b + ])); + a = new is.In([ + 2, + 4 + ]); + b = new is.LessThanEqual(1); + assert.deepEqual(set.difference(b, a), b); + } + }, + In_And: { + union: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + a, + b + ])); + a = new is.In([ + 15, + 16 + ]); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.union(a, b), b); + }, + intersection: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.intersection(a, b), set.EMPTY); + a = new is.In([ + 15, + 16 + ]); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.intersection(a, b), a); + }, + difference: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(a, b), a); + a = new is.In([ + 15, + 16 + ]); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(a, b), set.EMPTY); + } + }, + And_In: { + difference: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(b, a), b); + a = new is.In([ + 15, + 16 + ]); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + var res = set.difference(b, a); + assert.deepEqual(res, new is.And([ + new is.NotIn([ + 15, + 16 + ]), + b + ])); + } + }, + In_Or: { + union: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.Or([ + new is.GreaterThan(7), + new is.LessThan(1) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + a, + b + ])); + a = new is.In([ + 15, + 16 + ]); + b = new is.Or([ + new is.GreaterThan(7), + new is.LessThan(2) + ]); + assert.deepEqual(set.union(a, b), b); + var gt1 = new is.GreaterThan(1), lt1 = new is.LessThan(1), eq1 = new is.In([1]); + var intermediate = set.union(gt1, lt1); + var result = set.union(intermediate, eq1); + QUnit.equal(result, set.UNIVERSAL, 'foo > 1 || foo < 1 || foo === 1 => UNIVERSAL'); + }, + intersection: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.Or([ + new is.GreaterThan(7), + new is.LessThan(1) + ]); + assert.deepEqual(set.intersection(a, b), set.EMPTY); + a = new is.In([ + 15, + 16 + ]); + b = new is.Or([ + new is.GreaterThan(7), + new is.LessThan(2) + ]); + assert.deepEqual(set.intersection(a, b), a); + }, + difference: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.Or([ + new is.GreaterThan(7), + new is.LessThan(2) + ]); + assert.deepEqual(set.difference(a, b), a); + a = new is.In([ + 15, + 16 + ]); + b = new is.Or([ + new is.GreaterThan(7), + new is.LessThan(2) + ]); + assert.deepEqual(set.difference(a, b), set.EMPTY); + } + }, + Or_In: { + difference: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.Or([ + new is.GreaterThan(7), + new is.LessThan(2) + ]); + assert.deepEqual(set.difference(b, a), b); + a = new is.In([ + 15, + 16 + ]); + b = new is.Or([ + new is.GreaterThan(7), + new is.LessThan(2) + ]); + var res = set.difference(b, a); + assert.deepEqual(res, new is.And([ + new is.NotIn([ + 15, + 16 + ]), + b + ])); + } + }, + NotIn_NotIn: { + union: function (assert) { + var isNotIn5 = new is.NotIn([5]), isNotIn6 = new is.NotIn([6]); + assert.deepEqual(set.union(isNotIn5, isNotIn6), set.UNIVERSAL); + var a = new is.NotIn([ + 4, + 5 + ]), b = new is.NotIn([ + 5, + 6 + ]); + assert.deepEqual(set.union(a, b), new is.NotIn([5])); + }, + intersection: function (assert) { + var isNotIn5 = new is.NotIn([5]), isNotIn6 = new is.NotIn([6]); + assert.deepEqual(set.intersection(isNotIn5, isNotIn6), new is.NotIn([ + 5, + 6 + ])); + var in13 = new is.NotIn([ + 1, + 2, + 3 + ]), in24 = new is.NotIn([ + 2, + 3, + 4 + ]); + assert.deepEqual(set.intersection(in13, in24), new is.NotIn([ + 1, + 2, + 3, + 4 + ])); + }, + difference: function (assert) { + var isNotIn5 = new is.NotIn([5]), isNotIn6 = new is.NotIn([6]); + assert.deepEqual(set.difference(isNotIn5, isNotIn6), new is.In([5])); + var a = new is.NotIn([ + 2, + 3 + ]), b = new is.NotIn([ + 3, + 4 + ]); + assert.deepEqual(set.difference(a, b), new is.In([2])); + } + }, + UNIVERSAL_NotIn: { + difference: function (assert) { + var a = new is.NotIn([5]); + assert.deepEqual(set.difference(set.UNIVERSAL, a), new is.In([5])); + var b = new is.NotIn([ + 1, + 2, + 3 + ]); + assert.deepEqual(set.difference(set.UNIVERSAL, b), new is.In([ + 1, + 2, + 3 + ])); + } + }, + NotIn_isMember: function (assert) { + assert.notOk(new is.NotIn([5]).isMember(5)); + assert.ok(new is.NotIn([5]).isMember(6)); + assert.notOk(new is.NotIn([ + 5, + -1 + ]).isMember(-1)); + }, + NotIn_GreaterThan: { + union: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.GreaterThan(3); + assert.deepEqual(set.union(a, b), set.UNIVERSAL); + a = new is.NotIn([ + 2, + 4 + ]); + b = new is.GreaterThan(3); + assert.deepEqual(set.union(a, b), new is.NotIn([2])); + a = new is.NotIn([ + 2, + 4 + ]); + b = new is.GreaterThan(2); + assert.deepEqual(set.union(a, b), new is.NotIn([2])); + }, + intersection: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.GreaterThan(3), res; + res = set.intersection(a, b); + assert.deepEqual(res, new is.And([ + a, + b + ])); + a = new is.NotIn([ + 2, + 4 + ]); + b = new is.GreaterThan(3); + assert.deepEqual(set.intersection(a, b), new is.And([ + new is.NotIn([4]), + b + ])); + a = new is.NotIn([ + 2, + 4 + ]); + b = new is.GreaterThan(8); + assert.deepEqual(set.intersection(a, b), b); + }, + difference: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.GreaterThan(3); + assert.deepEqual(set.difference(a, b), new is.LessThanEqual(3)); + a = new is.NotIn([ + 2, + 4 + ]); + b = new is.GreaterThan(3); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.NotIn([2]), + new is.LessThanEqual(3) + ])); + a = new is.NotIn([ + 2, + 4 + ]); + b = new is.GreaterThan(8); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.NotIn([ + 2, + 4 + ]), + new is.LessThanEqual(8) + ])); + a = new is.NotIn([ + null, + undefined + ]); + b = new is.GreaterThan(8); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.NotIn([ + null, + undefined + ]), + new is.LessThanEqual(8) + ]), 'handles weird types'); + } + }, + GreaterThan_NotIn: { + difference: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.GreaterThan(3); + assert.deepEqual(set.difference(b, a), new is.In([ + 5, + 6 + ])); + a = new is.NotIn([ + 2, + 4 + ]); + b = new is.GreaterThan(3); + assert.deepEqual(set.difference(b, a), new is.In([4])); + a = new is.NotIn([ + 2, + 4 + ]); + b = new is.GreaterThan(8); + assert.deepEqual(set.difference(b, a), set.EMPTY); + a = new is.NotIn([ + null, + undefined + ]); + b = new is.GreaterThan(8); + assert.deepEqual(set.difference(b, a), set.EMPTY, 'handles weird types'); + } + }, + NotIn_GreaterThanEqual: { + union: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.GreaterThanEqual(3); + assert.deepEqual(set.union(a, b), set.UNIVERSAL); + a = new is.NotIn([ + 2, + 4 + ]); + b = new is.GreaterThanEqual(3); + assert.deepEqual(set.union(a, b), new is.NotIn([2])); + a = new is.NotIn([ + 2, + 4 + ]); + b = new is.GreaterThanEqual(2); + assert.deepEqual(set.union(a, b), set.UNIVERSAL); + }, + intersection: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.GreaterThanEqual(3), res; + res = set.intersection(a, b); + assert.deepEqual(res, new is.And([ + a, + b + ])); + a = new is.NotIn([ + 2, + 4 + ]); + b = new is.GreaterThanEqual(3); + assert.deepEqual(set.intersection(a, b), new is.And([ + new is.NotIn([4]), + b + ])); + a = new is.NotIn([ + 2, + 4 + ]); + b = new is.GreaterThanEqual(8); + assert.deepEqual(set.intersection(a, b), b); + }, + difference: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.GreaterThanEqual(3); + assert.deepEqual(set.difference(a, b), new is.LessThan(3)); + a = new is.NotIn([ + 2, + 4 + ]); + b = new is.GreaterThanEqual(3); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.NotIn([2]), + new is.LessThan(3) + ])); + a = new is.NotIn([ + 2, + 4 + ]); + b = new is.GreaterThanEqual(8); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.NotIn([ + 2, + 4 + ]), + new is.LessThan(8) + ])); + a = new is.NotIn([ + null, + undefined + ]); + b = new is.GreaterThanEqual(8); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.NotIn([ + null, + undefined + ]), + new is.LessThan(8) + ]), 'handles weird types'); + } + }, + GreaterThanEqual_NotIn: { + difference: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.GreaterThanEqual(3); + assert.deepEqual(set.difference(b, a), new is.In([ + 5, + 6 + ])); + a = new is.NotIn([ + 2, + 4 + ]); + b = new is.GreaterThanEqual(3); + assert.deepEqual(set.difference(b, a), new is.In([4])); + a = new is.NotIn([ + 2, + 4 + ]); + b = new is.GreaterThanEqual(8); + assert.deepEqual(set.difference(b, a), set.EMPTY); + a = new is.NotIn([2]); + b = new is.GreaterThanEqual(2); + assert.deepEqual(set.difference(b, a), new is.In([2])); + a = new is.NotIn([ + null, + undefined + ]); + b = new is.GreaterThanEqual(8); + assert.deepEqual(set.difference(b, a), set.EMPTY, 'handles weird types'); + } + }, + NotIn_LessThan: { + union: function (assert) { + var a = new is.NotIn([ + 5, + 7 + ]); + var b = new is.LessThan(6); + assert.deepEqual(set.union(a, b), new is.NotIn([7])); + }, + intersection: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.LessThan(7), res; + res = set.intersection(a, b); + assert.deepEqual(res, new is.And([ + a, + b + ])); + }, + difference: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.LessThan(7); + assert.deepEqual(set.difference(a, b), new is.GreaterThanEqual(7)); + } + }, + LessThan_NotIn: { + difference: function (assert) { + var a = new is.NotIn([ + 5, + 7 + ]); + var b = new is.LessThan(6); + assert.deepEqual(set.difference(b, a), new is.In([5])); + } + }, + NotIn_LessThanEqual: { + union: function (assert) { + var a = new is.NotIn([ + 5, + 7 + ]); + var b = new is.LessThanEqual(6); + assert.deepEqual(set.union(a, b), new is.NotIn([7])); + }, + intersection: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.LessThanEqual(7), res; + res = set.intersection(a, b); + assert.deepEqual(res, new is.And([ + a, + b + ])); + }, + difference: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.LessThanEqual(7); + assert.deepEqual(set.difference(a, b), new is.GreaterThan(7)); + a = new is.NotIn([ + 5, + 6 + ]); + b = new is.LessThanEqual(6); + assert.deepEqual(set.difference(a, b), new is.GreaterThan(6)); + a = new is.NotIn([ + 2, + 4 + ]); + b = new is.LessThanEqual(3); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.NotIn([4]), + new is.GreaterThan(3) + ])); + a = new is.NotIn([ + 2, + 4 + ]); + b = new is.LessThanEqual(1); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.NotIn([ + 2, + 4 + ]), + new is.GreaterThan(1) + ])); + a = new is.NotIn([undefined]); + b = new is.LessThanEqual(3); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.NotIn([undefined]), + new is.GreaterThan(3) + ])); + } + }, + LessThanEqual_NotIn: { + difference: function (assert) { + var a = new is.NotIn([ + 5, + 7 + ]); + var b = new is.LessThanEqual(6); + assert.deepEqual(set.difference(b, a), new is.In([5])); + } + }, + NotIn_And: { + union: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.union(a, b), a); + a = new is.NotIn([ + 15, + 16 + ]); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.union(a, b), set.UNIVERSAL); + }, + intersection: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.intersection(a, b), b); + a = new is.NotIn([ + 15, + 16 + ]); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.intersection(a, b), new is.And([ + a, + b + ]), 'not in within range'); + }, + difference: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + var res = set.difference(a, b); + assert.deepEqual(res, new is.And([ + a, + new is.Or([ + new is.GreaterThanEqual(20), + new is.LessThanEqual(7) + ]) + ])); + a = new is.NotIn([ + 15, + 16 + ]); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(a, b), new is.Or([ + new is.GreaterThanEqual(20), + new is.LessThanEqual(7) + ])); + } + }, + And_NotIn: { + difference: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(b, a), set.EMPTY); + a = new is.NotIn([ + 15, + 16 + ]); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + var res = set.difference(b, a); + assert.deepEqual(res, new is.In([ + 15, + 16 + ])); + } + }, + NotIn_Or: { + union: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.Or([ + new is.GreaterThan(7), + new is.LessThan(1) + ]); + assert.deepEqual(set.union(a, b), a); + a = new is.NotIn([ + 5, + 16 + ]); + b = new is.Or([ + new is.GreaterThan(7), + new is.LessThan(2) + ]); + assert.deepEqual(set.union(a, b), new is.NotIn([5])); + }, + intersection: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.Or([ + new is.GreaterThan(7), + new is.LessThan(1) + ]); + assert.deepEqual(set.intersection(a, b), b); + a = new is.NotIn([8]); + b = new is.Or([ + new is.GreaterThan(7), + new is.LessThan(2) + ]); + assert.deepEqual(set.intersection(a, b), new is.And([ + a, + b + ])); + }, + difference: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.Or([ + new is.GreaterThan(7), + new is.LessThan(2) + ]); + var res = set.difference(a, b); + assert.deepEqual(res, new is.And([ + a, + new is.And([ + new is.GreaterThanEqual(2), + new is.LessThanEqual(7) + ]) + ])); + a = new is.NotIn([ + 15, + 16 + ]); + b = new is.Or([ + new is.GreaterThan(7), + new is.LessThan(2) + ]); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.GreaterThanEqual(2), + new is.LessThanEqual(7) + ])); + } + }, + Or_NotIn: { + difference: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.Or([ + new is.GreaterThan(7), + new is.LessThan(2) + ]); + assert.deepEqual(set.difference(b, a), set.EMPTY, 'between'); + a = new is.NotIn([ + 15, + 16 + ]); + b = new is.Or([ + new is.GreaterThan(7), + new is.LessThan(2) + ]); + var res = set.difference(b, a); + assert.deepEqual(res, new is.In([ + 15, + 16 + ]), 'within'); + } + }, + GreaterThan_GreaterThan: { + union: function (assert) { + var a = new is.GreaterThan(5), b = new is.GreaterThan(6); + assert.deepEqual(set.union(a, b), a); + a = new is.GreaterThan('foo'); + b = new is.GreaterThan('bar'); + assert.deepEqual(set.union(a, b), b); + }, + intersection: function (assert) { + var a = new is.GreaterThan(5), b = new is.GreaterThan(6); + assert.deepEqual(set.intersection(a, b), b); + a = new is.GreaterThan('foo'); + b = new is.GreaterThan('bar'); + assert.deepEqual(set.intersection(a, b), a); + }, + difference: function (assert) { + var a = new is.GreaterThan(5), b = new is.GreaterThan(6); + assert.deepEqual(set.difference(a, b), new is.And([ + a, + new is.LessThanEqual(6) + ])); + a = new is.GreaterThan(5); + b = new is.GreaterThan(6); + assert.deepEqual(set.difference(b, a), set.EMPTY); + } + }, + GreaterThan_isMember: function (assert) { + assert.notOk(new is.GreaterThan(5).isMember(5)); + assert.ok(new is.GreaterThan(5).isMember(6)); + }, + UNIVERSAL_GreaterThan: { + difference: function (assert) { + var a = new is.GreaterThan(5); + assert.deepEqual(set.difference(set.UNIVERSAL, a), new is.LessThanEqual(5)); + } + }, + GreaterThan_GreaterThanEqual: { + union: function (assert) { + var a = new is.GreaterThan(5), b = new is.GreaterThanEqual(6); + assert.deepEqual(set.union(a, b), a); + a = new is.GreaterThan('foo'); + b = new is.GreaterThanEqual('bar'); + assert.deepEqual(set.union(a, b), b); + }, + intersection: function (assert) { + var a = new is.GreaterThan(5), b = new is.GreaterThanEqual(6); + assert.deepEqual(set.intersection(a, b), b); + a = new is.GreaterThan('foo'); + b = new is.GreaterThanEqual('bar'); + assert.deepEqual(set.intersection(a, b), a); + }, + difference: function (assert) { + var a = new is.GreaterThan(5), b = new is.GreaterThanEqual(6); + assert.deepEqual(set.difference(a, b), new is.And([ + a, + new is.LessThan(6) + ])); + a = new is.GreaterThan(6); + b = new is.GreaterThanEqual(5); + assert.deepEqual(set.difference(a, b), set.EMPTY); + a = new is.GreaterThan(5); + b = new is.GreaterThanEqual(5); + assert.deepEqual(set.difference(a, b), set.EMPTY); + } + }, + GreaterThanEqual_GreaterThan: { + difference: function (assert) { + var a = new is.GreaterThanEqual(5), b = new is.GreaterThan(6); + assert.deepEqual(set.difference(a, b), new is.And([ + a, + new is.LessThanEqual(6) + ])); + a = new is.GreaterThanEqual(6); + b = new is.GreaterThan(5); + assert.deepEqual(set.difference(a, b), set.EMPTY); + a = new is.GreaterThanEqual(5); + b = new is.GreaterThan(5); + assert.deepEqual(set.difference(a, b), new is.In([5])); + } + }, + GreaterThan_LessThan: { + union: function (assert) { + var a = new is.GreaterThan(5), b = new is.LessThan(6); + assert.deepEqual(set.union(a, b), set.UNIVERSAL); + a = new is.GreaterThan('foo'); + b = new is.LessThan('bar'); + assert.deepEqual(set.union(a, b), new is.Or([ + a, + b + ])); + a = new is.GreaterThan(5); + b = new is.LessThan(5); + assert.deepEqual(set.union(a, b), new is.NotIn([5])); + }, + intersection: function (assert) { + var a = new is.GreaterThan(5), b = new is.LessThan(6); + assert.deepEqual(set.intersection(a, b), new is.And([ + a, + b + ]), 'anded'); + a = new is.GreaterThan('foo'); + b = new is.LessThan('bar'); + assert.deepEqual(set.intersection(a, b), set.EMPTY); + a = new is.GreaterThan(20); + b = new is.LessThan(1); + assert.deepEqual(set.intersection(a, b), set.EMPTY); + }, + difference: function (assert) { + var a = new is.GreaterThan(5), b = new is.LessThan(6); + assert.deepEqual(set.difference(a, b), new is.GreaterThanEqual(6)); + a = new is.GreaterThan(6); + b = new is.LessThan(5); + assert.deepEqual(set.difference(a, b), a); + a = new is.GreaterThan(5); + b = new is.LessThan(5); + assert.deepEqual(set.difference(a, b), a); + } + }, + LessThan_GreaterThan: { + difference: function (assert) { + var a = new is.GreaterThan(5), b = new is.LessThan(6); + var res = set.difference(b, a); + assert.deepEqual(res, new is.LessThanEqual(5)); + a = new is.GreaterThan(6); + b = new is.LessThan(5); + assert.deepEqual(set.difference(b, a), b); + a = new is.GreaterThan(5); + b = new is.LessThan(5); + assert.deepEqual(set.difference(b, a), b); + } + }, + GreaterThan_LessThanEqual: { + union: function (assert) { + var a = new is.GreaterThan(5), b = new is.LessThanEqual(5); + assert.deepEqual(set.union(a, b), set.UNIVERSAL); + a = new is.GreaterThan('foo'); + b = new is.LessThanEqual('bar'); + assert.deepEqual(set.union(a, b), new is.Or([ + a, + b + ])); + }, + intersection: function (assert) { + var a = new is.GreaterThan(5), b = new is.LessThanEqual(6); + assert.deepEqual(set.intersection(a, b), new is.And([ + a, + b + ])); + a = new is.GreaterThan('foo'); + b = new is.LessThanEqual('bar'); + assert.deepEqual(set.intersection(a, b), set.EMPTY); + a = new is.GreaterThan(5); + b = new is.LessThanEqual(5); + assert.deepEqual(set.intersection(a, b), set.EMPTY); + }, + difference: function (assert) { + var a = new is.GreaterThan(5), b = new is.LessThanEqual(6); + assert.deepEqual(set.difference(a, b), new is.GreaterThan(6)); + a = new is.GreaterThan(6); + b = new is.LessThanEqual(5); + assert.deepEqual(set.difference(a, b), a); + a = new is.GreaterThan(5); + b = new is.LessThanEqual(5); + assert.deepEqual(set.difference(a, b), a); + } + }, + LessThanEqual_GreaterThan: { + difference: function (assert) { + var a = new is.GreaterThan(5), b = new is.LessThanEqual(6); + assert.deepEqual(set.difference(b, a), new is.LessThanEqual(5)); + a = new is.GreaterThan(6); + b = new is.LessThanEqual(5); + assert.deepEqual(set.difference(b, a), b); + a = new is.GreaterThan(5); + b = new is.LessThanEqual(5); + assert.deepEqual(set.difference(b, a), b); + } + }, + GreaterThan_And: { + union: function (assert) { + var a = new is.GreaterThan([10]); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.union(a, b), new is.GreaterThan(7)); + a = new is.GreaterThan(3); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.union(a, b), a); + a = new is.GreaterThan(21); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + a, + b + ])); + }, + intersection: function (assert) { + var a = new is.GreaterThan(5); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.intersection(a, b), b); + a = new is.GreaterThan(10); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.intersection(a, b), new is.And([ + new is.GreaterThan(10), + new is.LessThan(20) + ])); + a = new is.GreaterThan(25); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.intersection(a, b), set.EMPTY, 'should be empty'); + }, + difference: function (assert) { + var a = new is.GreaterThan(5); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(a, b), new is.Or([ + new is.And([ + a, + new is.LessThanEqual(7) + ]), + new is.GreaterThanEqual(20) + ]), 'wraps'); + a = new is.GreaterThan(10); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(a, b), new is.GreaterThanEqual(20), 'in between'); + a = new is.GreaterThan(25); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(a, b), a, 'outside'); + } + }, + And_GreaterThan: { + difference: function (assert) { + var a = new is.GreaterThan(5); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(b, a), set.EMPTY, 'within'); + a = new is.GreaterThan(10); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(b, a), new is.And([ + new is.GreaterThan(7), + new is.LessThanEqual(10) + ]), 'in between'); + a = new is.GreaterThan(25); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(b, a), b, 'outside'); + } + }, + GreaterThan_Or: { + union: function (assert) { + var a = new is.GreaterThan(10); + var b = new is.Or([ + new is.GreaterThan(20), + new is.LessThan(7) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + new is.GreaterThan(10), + new is.LessThan(7) + ])); + a = new is.GreaterThan(3); + assert.deepEqual(set.union(a, b), set.UNIVERSAL); + a = new is.GreaterThan(21); + assert.deepEqual(set.union(a, b), b); + a = new is.GreaterThan(0); + b = new is.Or([ + new is.GreaterThan(7), + new is.In([null]) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + new is.In([null]), + a + ]), 'union with a null'); + }, + intersection: function (assert) { + var a = new is.GreaterThan(10); + var b = new is.Or([ + new is.LessThan(7), + new is.GreaterThan(20) + ]); + assert.deepEqual(set.intersection(a, b), new is.GreaterThan(20)); + a = new is.GreaterThan(3); + assert.deepEqual(set.intersection(a, b), new is.Or([ + new is.GreaterThan(20), + new is.And([ + a, + new is.LessThan(7) + ]) + ])); + a = new is.GreaterThan(21); + assert.deepEqual(set.intersection(a, b), a); + }, + difference: function (assert) { + var a = new is.GreaterThan(10); + var b = new is.Or([ + new is.LessThan(7), + new is.GreaterThan(20) + ]); + assert.deepEqual(set.difference(a, b), new is.And([ + a, + new is.LessThanEqual(20) + ]), 'inside'); + a = new is.GreaterThan(3); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.GreaterThanEqual(7), + new is.LessThanEqual(20) + ]), 'left'); + a = new is.GreaterThan(21); + assert.deepEqual(set.difference(a, b), set.EMPTY, 'right'); + } + }, + Or_GreaterThan: { + difference: function (assert) { + var a = new is.GreaterThan(10); + var b = new is.Or([ + new is.LessThan(7), + new is.GreaterThan(20) + ]); + assert.deepEqual(set.difference(b, a), new is.LessThan(7), 'inside'); + a = new is.GreaterThan(3); + assert.deepEqual(set.difference(b, a), new is.LessThanEqual(3), 'left'); + a = new is.GreaterThan(21); + assert.deepEqual(set.difference(b, a), new is.Or([ + new is.LessThan(7), + new is.And([ + new is.GreaterThan(20), + new is.LessThanEqual(21) + ]) + ]), 'right'); + } + }, + GreaterThanEqual_GreaterThanEqual: { + union: function (assert) { + var a = new is.GreaterThanEqual(5), b = new is.GreaterThanEqual(6); + assert.deepEqual(set.union(a, b), a); + a = new is.GreaterThanEqual('foo'); + b = new is.GreaterThanEqual('bar'); + assert.deepEqual(set.union(a, b), b); + }, + intersection: function (assert) { + var a = new is.GreaterThanEqual(5), b = new is.GreaterThanEqual(6); + assert.deepEqual(set.intersection(a, b), b); + a = new is.GreaterThanEqual('foo'); + b = new is.GreaterThanEqual('bar'); + assert.deepEqual(set.intersection(a, b), a); + }, + difference: function (assert) { + var a = new is.GreaterThanEqual(5), b = new is.GreaterThanEqual(6); + assert.deepEqual(set.difference(a, b), new is.And([ + a, + new is.LessThan(6) + ])); + a = new is.GreaterThanEqual(5); + b = new is.GreaterThanEqual(6); + assert.deepEqual(set.difference(b, a), set.EMPTY); + } + }, + GreaterThanEqual_isMember: function (assert) { + assert.notOk(new is.GreaterThanEqual(5).isMember(4)); + assert.ok(new is.GreaterThanEqual(5).isMember(5)); + assert.ok(new is.GreaterThan(5).isMember(6)); + }, + UNIVERSAL_GreaterThanEqual: { + difference: function (assert) { + var a = new is.GreaterThanEqual(5); + assert.deepEqual(set.difference(set.UNIVERSAL, a), new is.LessThan(5)); + } + }, + GreaterThanEqual_LessThan: { + union: function (assert) { + var a = new is.GreaterThanEqual(5), b = new is.LessThan(6); + assert.deepEqual(set.union(a, b), set.UNIVERSAL); + a = new is.GreaterThanEqual('foo'); + b = new is.LessThan('bar'); + assert.deepEqual(set.union(a, b), new is.Or([ + a, + b + ])); + a = new is.GreaterThanEqual(5); + b = new is.LessThan(5); + assert.deepEqual(set.union(a, b), set.UNIVERSAL); + }, + intersection: function (assert) { + var a = new is.GreaterThanEqual(5), b = new is.LessThan(6); + assert.deepEqual(set.intersection(a, b), new is.And([ + a, + b + ]), 'anded'); + a = new is.GreaterThanEqual('foo'); + b = new is.LessThan('bar'); + assert.deepEqual(set.intersection(a, b), set.EMPTY); + a = new is.GreaterThanEqual(20); + b = new is.LessThan(1); + assert.deepEqual(set.intersection(a, b), set.EMPTY); + a = new is.GreaterThanEqual(20); + b = new is.LessThan(20); + assert.deepEqual(set.intersection(a, b), set.EMPTY); + }, + difference: function (assert) { + var a = new is.GreaterThanEqual(5), b = new is.LessThan(6); + assert.deepEqual(set.difference(a, b), new is.GreaterThanEqual(6)); + a = new is.GreaterThanEqual(6); + b = new is.LessThan(5); + assert.deepEqual(set.difference(a, b), a); + a = new is.GreaterThanEqual(5); + b = new is.LessThan(5); + assert.deepEqual(set.difference(a, b), a); + } + }, + LessThan_GreaterThanEqual: { + difference: function (assert) { + var a = new is.GreaterThanEqual(5), b = new is.LessThan(6); + assert.deepEqual(set.difference(b, a), new is.LessThan(5)); + a = new is.GreaterThanEqual(6); + b = new is.LessThan(5); + assert.deepEqual(set.difference(b, a), b); + a = new is.GreaterThanEqual(5); + b = new is.LessThan(5); + assert.deepEqual(set.difference(b, a), b); + } + }, + GreaterThanEqual_LessThanEqual: { + union: function (assert) { + var a = new is.GreaterThanEqual(5), b = new is.LessThanEqual(6); + assert.deepEqual(set.union(a, b), set.UNIVERSAL); + a = new is.GreaterThanEqual('foo'); + b = new is.LessThanEqual('bar'); + assert.deepEqual(set.union(a, b), new is.Or([ + a, + b + ])); + a = new is.GreaterThanEqual(5); + b = new is.LessThanEqual(5); + assert.deepEqual(set.union(a, b), set.UNIVERSAL); + }, + intersection: function (assert) { + var a = new is.GreaterThanEqual(5), b = new is.LessThanEqual(6); + assert.deepEqual(set.intersection(a, b), new is.And([ + a, + b + ]), 'anded'); + a = new is.GreaterThanEqual('foo'); + b = new is.LessThanEqual('bar'); + assert.deepEqual(set.intersection(a, b), set.EMPTY); + a = new is.GreaterThanEqual(20); + b = new is.LessThanEqual(1); + assert.deepEqual(set.intersection(a, b), set.EMPTY); + a = new is.GreaterThanEqual(5); + b = new is.LessThanEqual(5); + assert.deepEqual(set.intersection(a, b), new is.In([5])); + a = new is.GreaterThanEqual('foo'); + b = new is.LessThanEqual('foo'); + assert.deepEqual(set.intersection(a, b), new is.In(['foo'])); + }, + difference: function (assert) { + var a = new is.GreaterThanEqual(5), b = new is.LessThanEqual(6); + assert.deepEqual(set.difference(a, b), new is.GreaterThan(6)); + a = new is.GreaterThanEqual(6); + b = new is.LessThanEqual(5); + assert.deepEqual(set.difference(a, b), a); + a = new is.GreaterThanEqual(5); + b = new is.LessThanEqual(5); + assert.deepEqual(set.difference(a, b), new is.GreaterThan(5)); + } + }, + LessThanEqual_GreaterThanEqual: { + difference: function (assert) { + var a = new is.GreaterThanEqual(5), b = new is.LessThanEqual(6); + assert.deepEqual(set.difference(b, a), new is.LessThan(5)); + a = new is.GreaterThanEqual(6); + b = new is.LessThanEqual(5); + assert.deepEqual(set.difference(b, a), b); + a = new is.GreaterThanEqual(5); + b = new is.LessThanEqual(5); + assert.deepEqual(set.difference(b, a), new is.LessThan(5)); + } + }, + GreaterThanEqual_And: { + union: function (assert) { + var a = new is.GreaterThanEqual([10]); + var b = new is.And([ + new is.GreaterThanEqual(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.union(a, b), new is.GreaterThanEqual(7)); + a = new is.GreaterThanEqual(3); + assert.deepEqual(set.union(a, b), a); + a = new is.GreaterThanEqual(21); + assert.deepEqual(set.union(a, b), new is.Or([ + a, + b + ])); + }, + intersection: function (assert) { + var a = new is.GreaterThanEqual(5); + var b = new is.And([ + new is.GreaterThanEqual(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.intersection(a, b), b); + a = new is.GreaterThanEqual(10); + assert.deepEqual(set.intersection(a, b), new is.And([ + new is.GreaterThanEqual(10), + new is.LessThan(20) + ])); + a = new is.GreaterThanEqual(25); + assert.deepEqual(set.intersection(a, b), set.EMPTY, 'should be empty'); + }, + difference: function (assert) { + var a = new is.GreaterThan(5); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(a, b), new is.Or([ + new is.And([ + a, + new is.LessThanEqual(7) + ]), + new is.GreaterThanEqual(20) + ]), 'wraps'); + a = new is.GreaterThan(10); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(a, b), new is.GreaterThanEqual(20), 'in between'); + a = new is.GreaterThan(25); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(a, b), a, 'outside'); + } + }, + And_GreaterThanEqual: { + difference: function (assert) { + var a = new is.GreaterThanEqual(5); + var b = new is.And([ + new is.GreaterThanEqual(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(b, a), set.EMPTY, 'within'); + a = new is.GreaterThanEqual(10); + assert.deepEqual(set.difference(b, a), new is.And([ + new is.GreaterThanEqual(7), + new is.LessThan(10) + ]), 'in between'); + a = new is.GreaterThanEqual(25); + assert.deepEqual(set.difference(b, a), b, 'outside'); + } + }, + GreaterThanEqual_Or: { + union: function (assert) { + var a = new is.GreaterThanEqual(10); + var b = new is.Or([ + new is.GreaterThanEqual(20), + new is.LessThan(7) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + new is.GreaterThanEqual(10), + new is.LessThan(7) + ])); + a = new is.GreaterThanEqual(3); + assert.deepEqual(set.union(a, b), set.UNIVERSAL); + a = new is.GreaterThanEqual(21); + assert.deepEqual(set.union(a, b), b); + a = new is.GreaterThanEqual(0); + b = new is.Or([ + new is.GreaterThanEqual(7), + new is.In([null]) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + new is.In([null]), + a + ]), 'union with a null'); + }, + intersection: function (assert) { + var a = new is.GreaterThanEqual(10); + var b = new is.Or([ + new is.LessThan(7), + new is.GreaterThanEqual(20) + ]); + assert.deepEqual(set.intersection(a, b), new is.GreaterThanEqual(20)); + a = new is.GreaterThanEqual(3); + assert.deepEqual(set.intersection(a, b), new is.Or([ + new is.GreaterThanEqual(20), + new is.And([ + a, + new is.LessThan(7) + ]) + ])); + a = new is.GreaterThanEqual(21); + assert.deepEqual(set.intersection(a, b), a); + }, + difference: function (assert) { + var a = new is.GreaterThanEqual(10); + var b = new is.Or([ + new is.LessThan(7), + new is.GreaterThanEqual(20) + ]); + var res = set.difference(a, b); + assert.deepEqual(res, new is.And([ + a, + new is.LessThan(20) + ]), 'inside'); + a = new is.GreaterThan(3); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.GreaterThanEqual(7), + new is.LessThan(20) + ]), 'left'); + a = new is.GreaterThanEqual(21); + assert.deepEqual(set.difference(a, b), set.EMPTY, 'right'); + } + }, + Or_GreaterThanEqual: { + difference: function (assert) { + var a = new is.GreaterThanEqual(10); + var b = new is.Or([ + new is.LessThan(7), + new is.GreaterThanEqual(20) + ]); + assert.deepEqual(set.difference(b, a), new is.LessThan(7), 'inside'); + a = new is.GreaterThanEqual(3); + assert.deepEqual(set.difference(b, a), new is.LessThan(3), 'left'); + a = new is.GreaterThanEqual(21); + assert.deepEqual(set.difference(b, a), new is.Or([ + new is.LessThan(7), + new is.And([ + new is.GreaterThanEqual(20), + new is.LessThan(21) + ]) + ]), 'right'); + } + }, + LessThan_LessThan: { + union: function (assert) { + var a = new is.LessThan(5), b = new is.LessThan(6); + assert.deepEqual(set.union(a, b), b); + a = new is.LessThan('foo'); + b = new is.LessThan('bar'); + assert.deepEqual(set.union(a, b), a); + }, + intersection: function (assert) { + var a = new is.LessThan(5), b = new is.LessThan(6); + assert.deepEqual(set.intersection(a, b), a); + a = new is.LessThan('foo'); + b = new is.LessThan('bar'); + assert.deepEqual(set.intersection(a, b), b); + }, + difference: function (assert) { + var a = new is.LessThan(5), b = new is.LessThan(6); + assert.deepEqual(set.difference(a, b), set.EMPTY); + assert.deepEqual(set.difference(b, a), new is.And([ + b, + new is.GreaterThanEqual(5) + ])); + } + }, + LessThan_isMember: function (assert) { + assert.ok(new is.LessThan(5).isMember(4)); + assert.notOk(new is.LessThan(5).isMember(5)); + assert.notOk(new is.LessThan(5).isMember(6)); + }, + UNIVERSAL_LessThan: { + difference: function (assert) { + var a = new is.LessThan(5); + assert.deepEqual(set.difference(set.UNIVERSAL, a), new is.GreaterThanEqual(5)); + } + }, + LessThan_LessThanEqual: { + union: function (assert) { + var a = new is.LessThan(5), b = new is.LessThanEqual(6); + assert.deepEqual(set.union(a, b), b); + a = new is.LessThan('foo'); + b = new is.LessThanEqual('bar'); + assert.deepEqual(set.union(a, b), a); + }, + intersection: function (assert) { + var a = new is.LessThan(5), b = new is.LessThanEqual(6); + assert.deepEqual(set.intersection(a, b), a); + a = new is.LessThan('foo'); + b = new is.LessThanEqual('bar'); + assert.deepEqual(set.intersection(a, b), b); + }, + difference: function (assert) { + var a = new is.LessThan(5), b = new is.LessThanEqual(6); + assert.deepEqual(set.difference(a, b), set.EMPTY); + a = new is.LessThan(6); + b = new is.LessThanEqual(5); + assert.deepEqual(set.difference(a, b), new is.And([ + a, + new is.GreaterThan(5) + ])); + a = new is.LessThan(7); + b = new is.LessThanEqual(5); + assert.deepEqual(set.difference(a, b), new is.And([ + a, + new is.GreaterThan(5) + ])); + a = new is.LessThan(5); + b = new is.LessThanEqual(5); + assert.deepEqual(set.difference(a, b), set.EMPTY); + } + }, + LessThanEqual_LessThan: { + union: function (assert) { + var a = new is.LessThanEqual(5), b = new is.LessThan(6); + assert.deepEqual(set.union(a, b), b); + a = new is.LessThanEqual('foo'); + b = new is.LessThan('bar'); + assert.deepEqual(set.union(a, b), a); + }, + intersection: function (assert) { + var a = new is.LessThanEqual(5), b = new is.LessThan(6); + assert.deepEqual(set.intersection(a, b), a); + a = new is.LessThanEqual('foo'); + b = new is.LessThan('bar'); + assert.deepEqual(set.intersection(a, b), b); + }, + difference: function (assert) { + var a = new is.LessThanEqual(5), b = new is.LessThan(6); + assert.deepEqual(set.difference(a, b), set.EMPTY); + a = new is.LessThanEqual(6); + b = new is.LessThan(5); + assert.deepEqual(set.difference(a, b), new is.And([ + a, + new is.GreaterThanEqual(5) + ])); + a = new is.LessThanEqual(5); + b = new is.LessThan(5); + assert.deepEqual(set.difference(a, b), new is.In([5])); + } + }, + LessThan_And: { + union: function (assert) { + var a = new is.LessThan(10); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.union(a, b), new is.LessThan(20)); + a = new is.LessThan(33); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.union(a, b), a); + a = new is.LessThan(6); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + a, + b + ])); + }, + intersection: function (assert) { + var a = new is.LessThan(21); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.intersection(a, b), b); + a = new is.LessThan(10); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.intersection(a, b), new is.And([ + new is.GreaterThan(7), + new is.LessThan(10) + ])); + a = new is.LessThan(6); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.intersection(a, b), set.EMPTY, 'should be empty'); + }, + difference: function (assert) { + var a = new is.LessThan(21); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(a, b), new is.Or([ + new is.LessThanEqual(7), + new is.And([ + a, + new is.GreaterThanEqual(20) + ]) + ]), 'wraps'); + a = new is.LessThan(10); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(a, b), new is.LessThanEqual(7), 'in between'); + a = new is.LessThan(3); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(a, b), a, 'outside'); + } + }, + And_LessThan: { + difference: function (assert) { + var a = new is.LessThan(21); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(b, a), set.EMPTY, 'within'); + a = new is.LessThan(10); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(b, a), new is.And([ + new is.GreaterThanEqual(10), + new is.LessThan(20) + ]), 'in between'); + a = new is.LessThan(4); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(b, a), b, 'outside'); + } + }, + LessThan_Or: { + union: function (assert) { + var a = new is.LessThan(10); + var b = new is.Or([ + new is.GreaterThan(20), + new is.LessThan(7) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + new is.GreaterThan(20), + new is.LessThan(10) + ])); + a = new is.LessThan(21); + assert.deepEqual(set.union(a, b), set.UNIVERSAL); + a = new is.LessThan(6); + assert.deepEqual(set.union(a, b), b); + a = new is.LessThan(7); + b = new is.Or([ + new is.LessThan(0), + new is.In([null]) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + new is.In([null]), + a + ]), 'union with a null'); + }, + intersection: function (assert) { + var a = new is.LessThan(10); + var b = new is.Or([ + new is.LessThan(7), + new is.GreaterThan(20) + ]); + assert.deepEqual(set.intersection(a, b), new is.LessThan(7)); + a = new is.LessThan(33); + assert.deepEqual(set.intersection(a, b), new is.Or([ + new is.LessThan(7), + new is.And([ + new is.GreaterThan(20), + a + ]) + ])); + a = new is.LessThan(6); + assert.deepEqual(set.intersection(a, b), a); + }, + difference: function (assert) { + var a = new is.LessThan(10); + var b = new is.Or([ + new is.LessThan(7), + new is.GreaterThan(20) + ]); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.GreaterThanEqual(7), + a + ]), 'inside'); + a = new is.LessThan(33); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.GreaterThanEqual(7), + new is.LessThanEqual(20) + ]), 'left'); + a = new is.LessThan(6); + assert.deepEqual(set.difference(a, b), set.EMPTY, 'right'); + } + }, + Or_LessThan: { + difference: function (assert) { + var a = new is.LessThan(10); + var b = new is.Or([ + new is.LessThan(7), + new is.GreaterThan(20) + ]); + assert.deepEqual(set.difference(b, a), new is.GreaterThan(20), 'inside'); + a = new is.LessThan(33); + assert.deepEqual(set.difference(b, a), new is.GreaterThanEqual(33), 'left'); + a = new is.LessThan(6); + assert.deepEqual(set.difference(b, a), new is.Or([ + new is.GreaterThan(20), + new is.And([ + new is.LessThan(7), + new is.GreaterThanEqual(6) + ]) + ]), 'right'); + } + }, + LessThanEqual_LessThanEqual: { + union: function (assert) { + var a = new is.LessThanEqual(5), b = new is.LessThanEqual(6); + assert.deepEqual(set.union(a, b), b); + a = new is.LessThanEqual('foo'); + b = new is.LessThanEqual('bar'); + assert.deepEqual(set.union(a, b), a); + }, + intersection: function (assert) { + var a = new is.LessThanEqual(5), b = new is.LessThanEqual(6); + assert.deepEqual(set.intersection(a, b), a); + a = new is.LessThanEqual('foo'); + b = new is.LessThanEqual('bar'); + assert.deepEqual(set.intersection(a, b), b); + }, + difference: function (assert) { + var a = new is.LessThanEqual(5), b = new is.LessThanEqual(6); + assert.deepEqual(set.difference(a, b), set.EMPTY); + assert.deepEqual(set.difference(b, a), new is.And([ + b, + new is.GreaterThan(5) + ])); + } + }, + LessThanEqual_isMember: function (assert) { + assert.ok(new is.LessThanEqual(5).isMember(4)); + assert.ok(new is.LessThanEqual(5).isMember(5)); + assert.notOk(new is.LessThanEqual(5).isMember(6)); + }, + UNIVERSAL_LessThanEqual: { + difference: function (assert) { + var a = new is.LessThanEqual(5); + assert.deepEqual(set.difference(set.UNIVERSAL, a), new is.GreaterThan(5)); + } + }, + LessThanEqual_And: { + union: function (assert) { + var a = new is.LessThanEqual(10); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.union(a, b), new is.LessThan(20)); + a = new is.LessThanEqual(33); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.union(a, b), a); + a = new is.LessThanEqual(6); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + a, + b + ])); + }, + intersection: function (assert) { + var a = new is.LessThanEqual(0); + var b = new is.And([ + new is.GreaterThanEqual(0), + new is.LessThan(1) + ]); + assert.deepEqual(set.intersection(a, b), new is.In([0]), 'overlap to in'); + }, + difference: function (assert) { + var a = new is.LessThanEqual(21); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(a, b), new is.Or([ + new is.LessThanEqual(7), + new is.And([ + a, + new is.GreaterThanEqual(20) + ]) + ]), 'wraps'); + a = new is.LessThanEqual(10); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(a, b), new is.LessThanEqual(7), 'in between'); + a = new is.LessThanEqual(3); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(a, b), a, 'outside'); + } + }, + And_LessThanEqual: { + difference: function (assert) { + var a = new is.LessThanEqual(21); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(b, a), set.EMPTY, 'within'); + a = new is.LessThanEqual(10); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(b, a), new is.And([ + new is.GreaterThan(10), + new is.LessThan(20) + ]), 'in between'); + a = new is.LessThanEqual(4); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(b, a), b, 'outside'); + } + }, + LessThanEqual_Or: { + union: function (assert) { + var a = new is.LessThanEqual(10); + var b = new is.Or([ + new is.GreaterThan(20), + new is.LessThan(7) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + new is.GreaterThan(20), + new is.LessThanEqual(10) + ])); + a = new is.LessThanEqual(21); + assert.deepEqual(set.union(a, b), set.UNIVERSAL); + a = new is.LessThanEqual(6); + assert.deepEqual(set.union(a, b), b); + a = new is.LessThanEqual(7); + b = new is.Or([ + new is.LessThan(0), + new is.In([null]) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + new is.In([null]), + a + ]), 'union with a null'); + }, + intersection: function (assert) { + var a = new is.LessThanEqual(10); + var b = new is.Or([ + new is.LessThanEqual(7), + new is.GreaterThan(20) + ]); + assert.deepEqual(set.intersection(a, b), new is.LessThanEqual(7)); + a = new is.LessThanEqual(33); + assert.deepEqual(set.intersection(a, b), new is.Or([ + new is.LessThanEqual(7), + new is.And([ + new is.GreaterThan(20), + a + ]) + ])); + a = new is.LessThanEqual(6); + assert.deepEqual(set.intersection(a, b), a); + }, + difference: function (assert) { + var a = new is.LessThanEqual(10); + var b = new is.Or([ + new is.LessThan(7), + new is.GreaterThan(20) + ]); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.GreaterThanEqual(7), + a + ]), 'inside'); + a = new is.LessThanEqual(33); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.GreaterThanEqual(7), + new is.LessThanEqual(20) + ]), 'left'); + a = new is.LessThanEqual(6); + assert.deepEqual(set.difference(a, b), set.EMPTY, 'right'); + } + }, + Or_LessThanEqual: { + difference: function (assert) { + var a = new is.LessThanEqual(10); + var b = new is.Or([ + new is.LessThan(7), + new is.GreaterThan(20) + ]); + assert.deepEqual(set.difference(b, a), new is.GreaterThan(20), 'inside'); + a = new is.LessThanEqual(33); + assert.deepEqual(set.difference(b, a), new is.GreaterThan(33), 'left'); + a = new is.LessThanEqual(6); + assert.deepEqual(set.difference(b, a), new is.Or([ + new is.GreaterThan(20), + new is.And([ + new is.LessThan(7), + new is.GreaterThan(6) + ]) + ]), 'right'); + } + }, + And_And: { + union: function (assert) { + var a = new is.And([ + new is.GreaterThan(5), + new is.LessThan(10) + ]), b = new is.And([ + new is.GreaterThan(0), + new is.LessThan(6) + ]); + assert.deepEqual(set.union(a, b), new is.And([ + new is.GreaterThan(0), + new is.LessThan(10) + ]), 'able to combine sibling ands'); + a = new is.And([ + new is.LessThan(10), + new is.GreaterThan(5) + ]); + b = new is.And([ + new is.GreaterThan(0), + new is.LessThan(6) + ]); + assert.deepEqual(set.union(a, b), new is.And([ + new is.GreaterThan(0), + new is.LessThan(10) + ]), 'able to combine sibling ands'); + a = new is.And([ + new is.GreaterThan(5), + new is.LessThan(6) + ]); + b = new is.And([ + new is.GreaterThan(0), + new is.LessThan(10) + ]); + assert.deepEqual(set.union(a, b), new is.And([ + new is.GreaterThan(0), + new is.LessThan(10) + ]), 'able to combine inner and outer'); + a = new is.And([ + new is.GreaterThan(6), + new is.LessThan(10) + ]); + b = new is.And([ + new is.GreaterThan(0), + new is.LessThan(5) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + a, + b + ]), 'disjoint'); + }, + intersection: function (assert) { + var a = new is.And([ + new is.GreaterThan(5), + new is.LessThan(10) + ]), b = new is.And([ + new is.GreaterThan(0), + new is.LessThan(6) + ]); + assert.deepEqual(set.intersection(a, b), new is.And([ + new is.GreaterThan(5), + new is.LessThan(6) + ]), 'able to combine sibling ands'); + a = new is.And([ + new is.LessThan(10), + new is.GreaterThan(5) + ]); + b = new is.And([ + new is.GreaterThan(0), + new is.LessThan(6) + ]); + assert.deepEqual(set.intersection(a, b), new is.And([ + new is.GreaterThan(5), + new is.LessThan(6) + ]), 'able to combine sibling ands'); + a = new is.And([ + new is.GreaterThan(5), + new is.LessThan(6) + ]); + b = new is.And([ + new is.GreaterThan(0), + new is.LessThan(10) + ]); + assert.deepEqual(set.intersection(a, b), new is.And([ + new is.GreaterThan(5), + new is.LessThan(6) + ]), 'able to combine inner and outer'); + a = new is.And([ + new is.GreaterThan(6), + new is.LessThan(10) + ]); + b = new is.And([ + new is.GreaterThan(0), + new is.LessThan(5) + ]); + assert.deepEqual(set.intersection(a, b), set.EMPTY, 'disjoint'); + }, + difference: function (assert) { + var a = new is.And([ + new is.GreaterThan(5), + new is.LessThan(10) + ]), b = new is.And([ + new is.GreaterThan(0), + new is.LessThan(6) + ]); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.GreaterThanEqual(6), + new is.LessThan(10) + ]), 'diff right overlaps with left'); + assert.deepEqual(set.difference(b, a), new is.And([ + new is.GreaterThan(0), + new is.LessThanEqual(5) + ]), 'diff left overlaps with right'); + a = new is.And([ + new is.LessThan(10), + new is.GreaterThan(5) + ]); + b = new is.And([ + new is.GreaterThan(0), + new is.LessThan(6) + ]); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.GreaterThanEqual(6), + new is.LessThan(10) + ]), 'diff right overlaps with left (out of order)'); + assert.deepEqual(set.difference(b, a), new is.And([ + new is.GreaterThan(0), + new is.LessThanEqual(5) + ]), 'diff left overlaps with right (out of order)'); + a = new is.And([ + new is.GreaterThan(5), + new is.LessThan(6) + ]); + b = new is.And([ + new is.GreaterThan(0), + new is.LessThan(10) + ]); + assert.deepEqual(set.difference(a, b), set.EMPTY, 'able to inner \\ outer'); + assert.deepEqual(set.difference(b, a), new is.Or([ + new is.And([ + new is.GreaterThan(0), + new is.LessThanEqual(5) + ]), + new is.And([ + new is.GreaterThanEqual(6), + new is.LessThan(10) + ]) + ]), 'able to outer \\ inner'); + a = new is.And([ + new is.GreaterThan(6), + new is.LessThan(10) + ]); + b = new is.And([ + new is.GreaterThan(0), + new is.LessThan(5) + ]); + assert.deepEqual(set.difference(a, b), a, 'disjoint'); + assert.deepEqual(set.difference(b, a), b, 'disjoint'); + } + }, + And_isMember: function (assert) { + assert.ok(new is.And([ + new is.LessThan(5), + new is.GreaterThan(0) + ]).isMember(4)); + }, + UNIVERSAL_And: { + difference: function (assert) { + var a = new is.And([ + new is.GreaterThan(6), + new is.LessThan(10) + ]); + assert.deepEqual(set.difference(set.UNIVERSAL, a), new is.Or([ + new is.GreaterThanEqual(10), + new is.LessThanEqual(6) + ]), 'range and'); + } + }, + And_Or: { + union: function (assert) { + var a, b; + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]), b = new is.And([ + new is.GreaterThan(0), + new is.LessThan(6) + ]); + assert.deepEqual(set.union(a, b), set.UNIVERSAL, 'outer and inner'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]); + b = new is.And([ + new is.LessThan(6), + new is.GreaterThan(0) + ]); + assert.deepEqual(set.union(a, b), set.UNIVERSAL, 'outer and inner arg swap'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]); + b = new is.And([ + new is.LessThan(7), + new is.GreaterThan(-1) + ]); + assert.deepEqual(set.union(a, b), set.UNIVERSAL, 'imperfect outer and inner arg swap'); + a = new is.Or([ + new is.In([7]), + new is.LessThanEqual(0) + ]); + b = new is.And([ + new is.NotIn([7]), + new is.GreaterThan(0) + ]); + assert.deepEqual(set.union(a, b), set.UNIVERSAL, 'ins and notin'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]); + b = new is.And([ + new is.GreaterThan(0), + new is.LessThan(3) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + new is.GreaterThanEqual(6), + new is.LessThan(3) + ]), 'not a total overlap'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]); + b = new is.And([ + new is.GreaterThan(1), + new is.LessThan(5) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + b, + a + ]), 'disjoint'); + a = new is.Or([ + new is.LessThan(0), + new is.GreaterThan(20) + ]); + b = new is.And([ + new is.GreaterThan(0), + new is.LessThanEqual(20) + ]); + var result = set.union(a, b); + assert.deepEqual(result, new is.NotIn([0]), 'NotIn'); + }, + intersection: function (assert) { + var a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]); + var b = new is.And([ + new is.GreaterThan(1), + new is.LessThan(5) + ]); + assert.deepEqual(set.intersection(a, b), set.EMPTY, 'outer and inner disjoint'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]); + b = new is.And([ + new is.GreaterThanEqual(0), + new is.LessThanEqual(6) + ]); + assert.deepEqual(set.intersection(a, b), new is.In([ + 0, + 6 + ]), 'outer and inner overlap on values'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]); + b = new is.And([ + new is.GreaterThanEqual(6), + new is.LessThanEqual(10) + ]); + assert.deepEqual(set.intersection(a, b), b, 'and is entirely within part of or'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]); + b = new is.And([ + new is.GreaterThanEqual(4), + new is.LessThanEqual(10) + ]); + assert.deepEqual(set.intersection(a, b), new is.And([ + new is.GreaterThanEqual(6), + new is.LessThanEqual(10) + ]), 'and is entirely within part of or'); + a = new is.Or([ + new is.LessThanEqual(2), + new is.GreaterThanEqual(8) + ]); + b = new is.And([ + new is.GreaterThanEqual(0), + new is.LessThanEqual(10) + ]); + var res = set.intersection(a, b); + assert.deepEqual(res, new is.Or([ + new is.And([ + new is.GreaterThanEqual(0), + new is.LessThanEqual(2) + ]), + new is.And([ + new is.GreaterThanEqual(8), + new is.LessThanEqual(10) + ]) + ]), 'and is entirely within part of or'); + }, + difference: function (assert) { + var a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]), b = new is.And([ + new is.GreaterThan(0), + new is.LessThan(6) + ]); + assert.deepEqual(set.difference(b, a), b, 'outer and inner'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]); + b = new is.And([ + new is.LessThan(7), + new is.GreaterThan(-1) + ]); + assert.deepEqual(set.difference(b, a), new is.And([ + new is.GreaterThan(0), + new is.LessThan(6) + ]), 'imperfect outer and inner arg swap'); + a = new is.Or([ + new is.In([7]), + new is.LessThanEqual(0) + ]); + b = new is.And([ + new is.NotIn([7]), + new is.GreaterThan(0) + ]); + assert.deepEqual(set.difference(b, a), b, 'ins and notin'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]); + b = new is.And([ + new is.GreaterThan(0), + new is.LessThan(3) + ]); + assert.deepEqual(set.difference(b, a), b, 'not a total overlap'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]); + b = new is.And([ + new is.GreaterThan(1), + new is.LessThan(5) + ]); + assert.deepEqual(set.difference(b, a), b, 'disjoint'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]); + b = new is.And([ + new is.GreaterThanEqual(4), + new is.LessThanEqual(10) + ]); + assert.deepEqual(set.difference(b, a), new is.And([ + new is.GreaterThanEqual(4), + new is.LessThan(6) + ]), 'and is entirely within part of or'); + } + }, + Or_And: { + difference: function (assert) { + var a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]), b = new is.And([ + new is.GreaterThan(0), + new is.LessThan(6) + ]); + var res = set.difference(a, b); + assert.deepEqual(res, new is.Or([ + new is.GreaterThanEqual(6), + new is.LessThanEqual(0) + ]), 'outer and inner'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]); + b = new is.And([ + new is.LessThan(7), + new is.GreaterThan(-1) + ]); + assert.deepEqual(set.difference(a, b), new is.Or([ + new is.GreaterThanEqual(7), + new is.LessThanEqual(-1) + ]), 'imperfect outer and inner arg swap'); + a = new is.Or([ + new is.In([7]), + new is.LessThanEqual(0) + ]); + b = new is.And([ + new is.NotIn([7]), + new is.GreaterThan(0) + ]); + assert.deepEqual(set.difference(a, b), a, 'ins and notin'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]); + b = new is.And([ + new is.GreaterThan(0), + new is.LessThan(3) + ]); + assert.deepEqual(set.difference(a, b), new is.Or([ + new is.GreaterThanEqual(6), + new is.LessThanEqual(0) + ]), 'not a total overlap'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]); + b = new is.And([ + new is.GreaterThan(1), + new is.LessThan(5) + ]); + assert.deepEqual(set.difference(a, b), new is.Or([ + new is.GreaterThanEqual(6), + new is.LessThanEqual(0) + ]), 'disjoint'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]); + b = new is.And([ + new is.GreaterThanEqual(4), + new is.LessThanEqual(10) + ]); + assert.deepEqual(set.difference(a, b), new is.Or([ + new is.GreaterThan(10), + new is.LessThanEqual(0) + ]), 'and is entirely within part of or'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]); + b = new is.And([ + new is.LessThanEqual(10), + new is.GreaterThanEqual(4) + ]); + assert.deepEqual(set.difference(a, b), new is.Or([ + new is.GreaterThan(10), + new is.LessThanEqual(0) + ]), 'and is entirely within part of or reverse and'); + a = new is.Or([ + new is.GreaterThanEqual(6), + new is.LessThanEqual(0) + ]); + b = new is.And([ + new is.LessThanEqual(10), + new is.GreaterThanEqual(4) + ]); + assert.deepEqual(set.difference(a, b), new is.Or([ + new is.GreaterThan(10), + new is.LessThanEqual(0) + ]), 'and is entirely within part of or reversed or'); + } + }, + Or_Or: { + union: function (assert) { + var a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(10) + ]); + var b = new is.Or([ + new is.LessThanEqual(10), + new is.GreaterThanEqual(20) + ]); + assert.deepEqual(set.union(a, b), set.UNIVERSAL, 'separate holes'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(10) + ]); + b = new is.Or([ + new is.LessThanEqual(5), + new is.GreaterThanEqual(15) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + new is.GreaterThanEqual(10), + new is.LessThanEqual(5) + ]), 'overlapping holes'); + a = new is.Or([ + new is.In([0]), + new is.GreaterThanEqual(10) + ]); + b = new is.Or([ + new is.LessThanEqual(5), + new is.GreaterThanEqual(15) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + new is.GreaterThanEqual(10), + new is.LessThanEqual(5) + ]), 'overlapping holes with a single value'); + a = new is.Or([ + new is.In([0]), + new is.GreaterThanEqual(10) + ]); + b = new is.Or([ + new is.In([5]), + new is.GreaterThanEqual(15) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + new is.In([ + 0, + 5 + ]), + new is.GreaterThanEqual(10) + ]), 'overlapping holes with two values'); + a = new is.Or([ + new is.In([0]), + new is.LessThanEqual(10) + ]); + b = new is.Or([ + new is.In([5]), + new is.GreaterThanEqual(15) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + new is.GreaterThanEqual(15), + new is.LessThanEqual(10) + ]), 'other directional holes'); + }, + intersection: function (assert) { + var a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(10) + ]); + var b = new is.Or([ + new is.LessThanEqual(10), + new is.GreaterThanEqual(20) + ]); + assert.deepEqual(set.intersection(a, b), new is.Or([ + new is.GreaterThanEqual(20), + new is.Or([ + new is.In([10]), + new is.LessThanEqual(0) + ]) + ]), 'separate holes'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(10) + ]); + b = new is.Or([ + new is.LessThanEqual(5), + new is.GreaterThanEqual(15) + ]); + assert.deepEqual(set.intersection(a, b), new is.Or([ + new is.GreaterThanEqual(15), + new is.LessThanEqual(0) + ]), 'overlapping holes'); + a = new is.Or([ + new is.In([0]), + new is.GreaterThanEqual(10) + ]); + b = new is.Or([ + new is.LessThanEqual(5), + new is.GreaterThanEqual(15) + ]); + assert.deepEqual(set.intersection(a, b), new is.Or([ + new is.In([0]), + new is.GreaterThanEqual(15) + ]), 'overlapping holes with a single value'); + a = new is.Or([ + new is.In([0]), + new is.GreaterThanEqual(10) + ]); + b = new is.Or([ + new is.In([5]), + new is.GreaterThanEqual(15) + ]); + assert.deepEqual(set.intersection(a, b), new is.GreaterThanEqual(15), 'overlapping holes with two values'); + a = new is.Or([ + new is.In([0]), + new is.LessThanEqual(10) + ]); + b = new is.Or([ + new is.In([5]), + new is.GreaterThanEqual(15) + ]); + assert.deepEqual(set.intersection(a, b), new is.In([5]), 'other directional holes'); + a = new is.Or([ + new is.In([0]), + new is.LessThanEqual(-1) + ]); + b = new is.Or([ + new is.In([5]), + new is.GreaterThanEqual(15) + ]); + assert.deepEqual(set.intersection(a, b), set.EMPTY, 'other directional holes'); + a = new is.Or([ + new is.GreaterThanEqual(15), + new is.And([ + new is.GreaterThan(0), + new is.LessThanEqual(5) + ]) + ]); + b = new is.Or([ + new is.LessThanEqual(5), + new is.And([ + new is.GreaterThanEqual(15), + new is.LessThan(20) + ]) + ]); + assert.deepEqual(set.intersection(a, b), new is.Or([ + new is.And([ + new is.GreaterThan(0), + new is.LessThanEqual(5) + ]), + new is.And([ + new is.GreaterThanEqual(15), + new is.LessThan(20) + ]) + ]), 'or with ands'); + }, + difference: function (assert) { + var a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(10) + ]); + var b = new is.Or([ + new is.LessThanEqual(10), + new is.GreaterThanEqual(20) + ]); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.GreaterThan(10), + new is.LessThan(20) + ]), 'separate holes'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(10) + ]); + b = new is.Or([ + new is.LessThanEqual(5), + new is.GreaterThanEqual(15) + ]); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.GreaterThanEqual(10), + new is.LessThan(15) + ]), 'overlapping holes'); + a = new is.Or([ + new is.In([0]), + new is.GreaterThanEqual(10) + ]); + b = new is.Or([ + new is.LessThanEqual(5), + new is.GreaterThanEqual(15) + ]); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.GreaterThanEqual(10), + new is.LessThan(15) + ]), 'overlapping holes with a single value'); + a = new is.Or([ + new is.In([0]), + new is.GreaterThanEqual(10) + ]); + b = new is.Or([ + new is.In([5]), + new is.GreaterThanEqual(15) + ]); + assert.deepEqual(set.difference(a, b), new is.Or([ + new is.In([0]), + new is.And([ + new is.GreaterThanEqual(10), + new is.LessThan(15) + ]) + ]), 'overlapping holes with two values'); + a = new is.Or([ + new is.In([0]), + new is.LessThanEqual(-1) + ]); + b = new is.Or([ + new is.In([5]), + new is.GreaterThanEqual(15) + ]); + assert.deepEqual(set.difference(a, b), a, 'other directional holes'); + a = new is.Or([ + new is.LessThanEqual(5), + new is.GreaterThanEqual(15) + ]); + b = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(20) + ]); + var res = set.difference(a, b); + assert.deepEqual(res, new is.Or([ + new is.And([ + new is.GreaterThan(0), + new is.LessThanEqual(5) + ]), + new is.And([ + new is.GreaterThanEqual(15), + new is.LessThan(20) + ]) + ]), 'overlapping holes'); + } + }, + Or_isMember: function (assert) { + assert.notOk(new is.Or([ + new is.LessThan(0), + new is.GreaterThan(10) + ]).isMember(4)); + }, + UNIVERSAL_Or: { + difference: function (assert) { + var or = new is.Or([ + new is.LessThan(0), + new is.GreaterThan(10) + ]); + assert.deepEqual(set.difference(set.UNIVERSAL, or), new is.And([ + new is.GreaterThanEqual(0), + new is.LessThanEqual(10) + ]), 'other directional holes'); + } + } + }; + var makeTests = function (test, name1, name2, reversed, noDash) { + var dash = noDash ? '' : ' - - '; + if (reversed) { + if (test.difference) { + QUnit.test(dash + name1 + ' difference ' + name2, test.difference); + } else { + QUnit.skip(dash + name1 + ' difference ' + name2, function () { + }); + } + } else { + [ + 'union', + 'intersection', + 'difference' + ].forEach(function (prop) { + if (test[prop]) { + QUnit.test(dash + name1 + ' ' + prop + ' ' + name2, test[prop]); + } else { + QUnit.skip(dash + name1 + ' ' + prop + ' ' + name2, function () { + }); + } + }); + } + }; + var names = Object.keys(compare); + names.forEach(function (name1, i) { + if (!tests[name1 + '_' + name1]) { + QUnit.skip('' + name1 + '_' + name1 + '', function () { + }); + } else { + makeTests(tests[name1 + '_' + name1], name1, name1, false, true); + } + if (!tests[name1 + '_isMember']) { + QUnit.skip(' - ' + name1 + '_isMember', function () { + }); + } else { + QUnit.test(' - ' + name1 + '_isMember', tests[name1 + '_isMember']); + } + if (!tests['UNIVERSAL_' + name1]) { + QUnit.skip(' - UNIVERSAL_' + name1 + '', function () { + }); + } else { + makeTests(tests['UNIVERSAL_' + name1], 'UNIVERSAL', name1, true); + } + for (var j = i + 1; j < names.length; j++) { + var name2 = names[j]; + if (!tests[name1 + '_' + name2]) { + QUnit.skip(' - ' + name1 + '_' + name2 + '', function () { + }); + } else { + makeTests(tests[name1 + '_' + name2], name1, name2); + } + if (!tests[name2 + '_' + name1]) { + QUnit.skip(' - ' + name2 + '_' + name1 + '', function () { + }); + } else { + makeTests(tests[name2 + '_' + name1], name2, name1, true); + } + } + }); + QUnit.test('Able to do membership, union, difference with GreaterThan', function () { + var DateStrSet = function (value) { + this.value = value; + }; + DateStrSet.prototype.valueOf = function () { + return new Date(this.value).getTime(); + }; + var date1980 = new Date(1980, 0, 1); + var greaterThan1980 = new compare.GreaterThan(new DateStrSet(date1980.toString())); + QUnit.ok(greaterThan1980.isMember(new Date(1982, 9, 20).toString()), 'is member'); + var greaterThan1990 = new compare.GreaterThan(new DateStrSet(new Date(1990, 0, 1).toString())); + var union = set.union(greaterThan1980, greaterThan1990); + QUnit.deepEqual(union, new compare.GreaterThan(new DateStrSet(date1980.toString())), 'union'); + var difference = set.difference(greaterThan1980, greaterThan1990); + var gt1980 = new compare.GreaterThan(new DateStrSet(date1980.toString())), lte1990 = new compare.LessThanEqual(new DateStrSet(new Date(1990, 0, 1).toString())); + QUnit.deepEqual(difference, new is.And([ + gt1980, + lte1990 + ]), 'difference'); + }); + QUnit.test('Able to do membership, union, difference with $in', function () { + var DateStrSet = function (value) { + this.value = value; + }; + DateStrSet.prototype.valueOf = function () { + return new Date(this.value).getTime(); + }; + var date1980 = new Date(1980, 0, 1).toString(), date1990 = new Date(1990, 0, 1).toString(), date2000 = new Date(2000, 0, 1).toString(); + var in80or90 = new compare.In([ + new DateStrSet(date1980), + new DateStrSet(date1990) + ]); + QUnit.ok(in80or90.isMember(date1980), 'is member'); + var in90or00 = new compare.In([ + new DateStrSet(date1990), + new DateStrSet(date2000) + ]); + var union = set.union(in80or90, in90or00); + QUnit.deepEqual(union, new compare.In([ + new DateStrSet(date1980), + new DateStrSet(date1990), + new DateStrSet(date2000) + ]), 'union'); + }); +}); +/*can-query-logic@1.1.6#src/types/types*/ +define('can-query-logic@1.1.6#src/types/types', function (require, exports, module) { + module.exports = {}; +}); +/*can-query-logic@1.1.6#src/types/values-or*/ +define('can-query-logic@1.1.6#src/types/values-or', [ + 'require', + 'exports', + 'module', + '../set', + './types' +], function (require, exports, module) { + var set = require('../set'); + var types = require('./types'); + function ValuesOr(values) { + this.values = values; + } + ValuesOr.prototype.isMember = function (props) { + return this.values.some(function (value) { + return value && value.isMember ? value.isMember(props) : value === props; + }); + }; + set.defineComparison(set.UNIVERSAL, ValuesOr, { + difference: function () { + return set.UNDEFINABLE; + } + }); + module.exports = types.ValuesOr = ValuesOr; +}); +/*can-query-logic@1.1.6#src/types/values-not*/ +define('can-query-logic@1.1.6#src/types/values-not', [ + 'require', + 'exports', + 'module', + '../set', + './types' +], function (require, exports, module) { + var set = require('../set'); + var keysLogic = require('./types'); + function NotIdentity(value) { + this.value = value; + } + var Identity = set.Identity; + set.defineComparison(set.UNIVERSAL, Identity, { + difference: function (universe, value) { + return new NotIdentity(value); + } + }); + set.defineComparison(set.UNIVERSAL, NotIdentity, { + difference: function (universe, not) { + return not.value; + } + }); + set.defineComparison(NotIdentity, NotIdentity, {}); + set.defineComparison(NotIdentity, Identity, { + union: function (not, primitive) { + if (set.isEqual(not.value, primitive)) { + return set.UNIVERSAL; + } else { + throw new Error('Not,Identity Union is not filled out'); + } + }, + intersection: function (not, primitive) { + return set.isEqual(!not.value, primitive) ? primitive : set.EMPTY; + }, + difference: function difference(not, primitive) { + if (set.isEqual(not.value, primitive)) { + return not; + } else { + return set.UNDEFINABLE; + } + } + }); + set.defineComparison(Identity, NotIdentity, { + difference: function (primitive, not) { + if (set.isEqual(primitive, not.value)) { + return primitive; + } else { + return set.UNDEFINABLE; + } + } + }); + module.exports = keysLogic.Not = NotIdentity; +}); +/*can-query-logic@1.1.6#src/types/keys-and*/ +define('can-query-logic@1.1.6#src/types/keys-and', [ + 'require', + 'exports', + 'module', + '../set', + 'can-assign', + '../array-union-intersection-difference', + 'can-reflect', + 'can-key/get/get', + 'can-symbol', + 'can-reflect', + './types' +], function (require, exports, module) { + var set = require('../set'); + var assign = require('can-assign'); + var arrayUnionIntersectionDifference = require('../array-union-intersection-difference'); + var canReflect = require('can-reflect'); + var canGet = require('can-key/get/get'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + var keysLogic = require('./types'); + function KeysAnd(values) { + var vals = this.values = {}; + canReflect.eachKey(values, function (value, key) { + if (canReflect.isPlainObject(value) && !set.isSpecial(value)) { + vals[key] = new KeysAnd(value); + } else { + vals[key] = value; + } + }); + } + var isMemberSymbol = canSymbol.for('can.isMember'); + KeysAnd.prototype.isMember = function (props, root, rootKey) { + var equal = true; + var preKey = rootKey ? rootKey + '.' : ''; + canReflect.eachKey(this.values, function (value, key) { + var isMember = value && (value[isMemberSymbol] || value.isMember); + if (isMember) { + if (!isMember.call(value, canGet(props, key), root || props, preKey + key)) { + equal = false; + } + } else { + if (value !== canGet(props, key)) { + equal = false; + } + } + }); + return equal; + }; + function checkIfUniversalAndReturnUniversal(setA) { + return set.isEqual(setA, set.UNIVERSAL) ? set.UNIVERSAL : setA; + } + var MISSING = {}; + function eachInUnique(a, acb, b, bcb, defaultReturn) { + var bCopy = assign({}, b), res; + for (var prop in a) { + res = acb(prop, a[prop], prop in b ? b[prop] : MISSING, a, b); + if (res !== undefined) { + return res; + } + delete bCopy[prop]; + } + for (prop in bCopy) { + res = bcb(prop, MISSING, b[prop], a, b); + if (res !== undefined) { + return res; + } + } + return defaultReturn; + } + function keyDiff(valuesA, valuesB) { + var keyResults = arrayUnionIntersectionDifference(Object.keys(valuesA), Object.keys(valuesB)); + return { + aOnlyKeys: keyResults.difference, + aAndBKeys: keyResults.intersection, + bOnlyKeys: arrayUnionIntersectionDifference(Object.keys(valuesB), Object.keys(valuesA)).difference + }; + } + function notEmpty(value) { + return value !== set.EMPTY; + } + function difference(objA, objB) { + var valuesA = objA.values, valuesB = objB.values, diff = keyDiff(valuesA, valuesB), aOnlyKeys = diff.aOnlyKeys, aAndBKeys = diff.aAndBKeys, bOnlyKeys = diff.bOnlyKeys; + var sharedKeysAndValues = {}, productAbleKeysAndData = {}, disjointKeysAndValues = {}; + aAndBKeys.forEach(function (key) { + var difference = set.difference(valuesA[key], valuesB[key]); + if (difference === set.EMPTY) { + sharedKeysAndValues[key] = valuesA[key]; + } else { + var intersection = set.intersection(valuesA[key], valuesB[key]); + var isProductable = intersection !== set.EMPTY; + if (isProductable) { + productAbleKeysAndData[key] = { + difference: difference, + intersection: intersection + }; + } else { + disjointKeysAndValues[key] = valuesA[key]; + } + } + }); + var productAbleKeys = Object.keys(productAbleKeysAndData); + var singleProductKeyAndValue; + if (productAbleKeys.length === 1) { + singleProductKeyAndValue = {}; + singleProductKeyAndValue[productAbleKeys[0]] = productAbleKeysAndData[productAbleKeys[0]].difference; + } + if (Object.keys(disjointKeysAndValues).length) { + return objA; + } + if (aOnlyKeys.length === 0 && bOnlyKeys.length === 0) { + if (productAbleKeys.length > 1) { + return set.UNDEFINABLE; + } else if (productAbleKeys.length === 1) { + assign(sharedKeysAndValues, singleProductKeyAndValue); + return new KeysAnd(sharedKeysAndValues); + } else { + return set.EMPTY; + } + } + if (aOnlyKeys.length > 0 && bOnlyKeys.length === 0) { + if (productAbleKeys.length > 1) { + return set.UNDEFINABLE; + } else if (productAbleKeys.length === 1) { + assign(sharedKeysAndValues, singleProductKeyAndValue); + aOnlyKeys.forEach(function (key) { + sharedKeysAndValues[key] = valuesA[key]; + }); + return new KeysAnd(sharedKeysAndValues); + } else { + return set.EMPTY; + } + } + if (aOnlyKeys.length === 0 && bOnlyKeys.length > 0) { + if (productAbleKeys.length > 1) { + return set.UNDEFINABLE; + } + var productAbleOr; + if (productAbleKeys.length === 1) { + var productableKey = productAbleKeys[0]; + productAbleOr = assign({}, sharedKeysAndValues); + productAbleOr[productableKey] = productAbleKeysAndData[productableKey].difference; + sharedKeysAndValues[productableKey] = productAbleKeysAndData[productableKey].intersection; + } + var ands = bOnlyKeys.map(function (key) { + var shared = assign({}, sharedKeysAndValues); + var result = shared[key] = set.difference(set.UNIVERSAL, valuesB[key]); + return result === set.EMPTY ? result : new KeysAnd(shared); + }).filter(notEmpty); + if (productAbleOr) { + ands.push(new KeysAnd(productAbleOr)); + } + if (ands.length > 1) { + return new keysLogic.ValuesOr(ands); + } else if (ands.length === 1) { + return ands[0]; + } else { + return set.EMPTY; + } + } + if (aOnlyKeys.length > 0 && bOnlyKeys.length > 0) { + if (productAbleKeys.length) { + throw new Error('Can\'t handle any productable keys right now'); + } + aOnlyKeys.forEach(function (key) { + sharedKeysAndValues[key] = valuesA[key]; + }); + if (bOnlyKeys.length === 1) { + var key = bOnlyKeys[0]; + var shared = assign({}, sharedKeysAndValues); + shared[key] = set.difference(set.UNIVERSAL, valuesB[key]); + return new KeysAnd(shared); + } else { + return set.UNDEFINABLE; + } + } + } + set.defineComparison(KeysAnd, KeysAnd, { + union: function (objA, objB) { + var diff = keyDiff(objA.values, objB.values); + var aAndBKeysThatAreNotEqual = [], sameKeys = {}; + diff.aAndBKeys.forEach(function (key) { + if (!set.isEqual(objA.values[key], objB.values[key])) { + aAndBKeysThatAreNotEqual.push(key); + } else { + sameKeys[key] = objA.values[key]; + } + }); + var aUnequal = {}, bUnequal = {}; + aAndBKeysThatAreNotEqual.forEach(function (key) { + aUnequal[key] = objA.values[key]; + bUnequal[key] = objB.values[key]; + }); + if (!diff.aOnlyKeys.length && !diff.bOnlyKeys.length) { + if (aAndBKeysThatAreNotEqual.length === 1) { + var keyValue = aAndBKeysThatAreNotEqual[0]; + var result = sameKeys[keyValue] = set.union(objA.values[keyValue], objB.values[keyValue]); + return canReflect.size(sameKeys) === 1 && set.isEqual(result, set.UNIVERSAL) ? set.UNIVERSAL : new KeysAnd(sameKeys); + } else if (aAndBKeysThatAreNotEqual.length === 0) { + return objA; + } + } + if (aAndBKeysThatAreNotEqual.length === 0) { + if (diff.aOnlyKeys.length > 0 && diff.bOnlyKeys.length === 0) { + return checkIfUniversalAndReturnUniversal(objB); + } else if (diff.aOnlyKeys.length === 0 && diff.bOnlyKeys.length > 0) { + return checkIfUniversalAndReturnUniversal(objA); + } + } + if (diff.aOnlyKeys.length > 0 && diff.bOnlyKeys.length === 0) { + if (set.isSubset(new KeysAnd(aUnequal), new KeysAnd(bUnequal))) { + return objB; + } + } + if (diff.bOnlyKeys.length > 0 && diff.aOnlyKeys.length === 0) { + if (set.isSubset(new KeysAnd(bUnequal), new KeysAnd(aUnequal))) { + return objA; + } + } + return new keysLogic.ValuesOr([ + objA, + objB + ]); + }, + intersection: function (objA, objB) { + var valuesA = objA.values, valuesB = objB.values, foundEmpty = false; + var resultValues = {}; + eachInUnique(valuesA, function (prop, aVal, bVal) { + resultValues[prop] = bVal === MISSING ? aVal : set.intersection(aVal, bVal); + if (resultValues[prop] === set.EMPTY) { + foundEmpty = true; + } + }, valuesB, function (prop, aVal, bVal) { + resultValues[prop] = bVal; + if (resultValues[prop] === set.EMPTY) { + foundEmpty = true; + } + }); + if (foundEmpty) { + return set.EMPTY; + } else { + return new KeysAnd(resultValues); + } + }, + difference: difference + }); + set.defineComparison(set.UNIVERSAL, KeysAnd, { + difference: function (universe, and) { + return difference({ values: {} }, and); + } + }); + module.exports = keysLogic.KeysAnd = KeysAnd; +}); +/*can-query-logic@1.1.6#src/types/and-or-not*/ +define('can-query-logic@1.1.6#src/types/and-or-not', [ + 'require', + 'exports', + 'module', + './values-or', + './values-not', + './keys-and' +], function (require, exports, module) { + var ValuesOr = require('./values-or'); + var ValuesNot = require('./values-not'); + var KeysAnd = require('./keys-and'); + module.exports = { + KeysAnd: KeysAnd, + ValuesOr: ValuesOr, + ValuesNot: ValuesNot + }; +}); +/*can-query-logic@1.1.6#src/schema-helpers*/ +define('can-query-logic@1.1.6#src/schema-helpers', [ + 'require', + 'exports', + 'module', + 'can-reflect', + './set', + 'can-symbol' +], function (require, exports, module) { + var canReflect = require('can-reflect'); + var set = require('./set'); + var canSymbol = require('can-symbol'); + var schemaHelpers; + module.exports = schemaHelpers = { + isRangedType: function (Type) { + return Type && canReflect.isConstructorLike(Type) && !set.hasComparisons(Type) && !Type[canSymbol.for('can.SetType')] && Type.prototype.valueOf && Type.prototype.valueOf !== Object.prototype.valueOf; + }, + categorizeOrValues: function categorizeOrValues(values) { + var categories = { + primitives: [], + valueOfTypes: [], + others: [] + }; + values.forEach(function (value) { + if (canReflect.isPrimitive(value)) { + categories.primitives.push(value); + } else if (schemaHelpers.isRangedType(value)) { + categories.valueOfTypes.push(value); + } else { + categories.others.push(value); + } + }); + return categories; + } + }; +}); +/*can-query-logic@1.1.6#src/types/make-enum*/ +define('can-query-logic@1.1.6#src/types/make-enum', [ + 'require', + 'exports', + 'module', + '../set', + '../array-union-intersection-difference', + '../schema-helpers', + 'can-reflect', + 'can-symbol' +], function (require, exports, module) { + var set = require('../set'); + var arrayUnionIntersectionDifference = require('../array-union-intersection-difference'); + var schemaHelpers = require('../schema-helpers'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var setTypeSymbol = canSymbol.for('can.SetType'), isMemberSymbol = canSymbol.for('can.isMember'), newSymbol = canSymbol.for('can.new'); + function makeEnumSetType(allValues, hydrate) { + function Enum(values) { + var arr = Array.isArray(values) ? values : [values]; + this.values = hydrate ? arr.map(hydrate) : arr; + } + canReflect.assignSymbols(Enum.prototype, { + 'can.serialize': function () { + return this.values.length === 1 ? this.values[0] : this.values; + } + }); + Enum.prototype[isMemberSymbol] = function (value) { + return this.values.some(function (val) { + return set.isEqual(val, value); + }); + }; + Enum.UNIVERSAL = new Enum(allValues); + var difference = function (enum1, enum2) { + var result = arrayUnionIntersectionDifference(enum1.values, enum2.values); + if (result.difference.length) { + return new Enum(result.difference); + } else { + return set.EMPTY; + } + }; + set.defineComparison(Enum, Enum, { + union: function (enum1, enum2) { + var result = arrayUnionIntersectionDifference(enum1.values, enum2.values); + if (result.union.length) { + return new Enum(result.union); + } else { + return set.EMPTY; + } + }, + intersection: function (enum1, enum2) { + var result = arrayUnionIntersectionDifference(enum1.values, enum2.values); + if (result.intersection.length) { + return new Enum(result.intersection); + } else { + return set.EMPTY; + } + }, + difference: difference + }); + set.defineComparison(Enum, set.UNIVERSAL, { + difference: function (enumA) { + return difference(enumA, { values: allValues.slice(0) }); + } + }); + set.defineComparison(set.UNIVERSAL, Enum, { + difference: function (universe, enumB) { + return difference({ values: allValues.slice(0) }, enumB); + } + }); + return Enum; + } + function makeEnum(Type, allValues, hydrate) { + var Enum = makeEnumSetType(allValues, hydrate); + Type[setTypeSymbol] = Enum; + Type[isMemberSymbol] = function (value) { + return allValues.some(function (val) { + return set.isEqual(val, value); + }); + }; + return Enum; + } + makeEnum.canMakeEnumSetType = function (Type) { + var schema = canReflect.getSchema(Type); + if (schema && schema.type === 'Or') { + var categories = schemaHelpers.categorizeOrValues(schema.values); + return categories.primitives.length === schema.values.length; + } + return false; + }; + makeEnum.makeEnumSetType = function (Type) { + var schema = canReflect.getSchema(Type); + var categories = schemaHelpers.categorizeOrValues(schema.values); + var hydrate = Type[newSymbol] ? Type[newSymbol].bind(Type) : undefined; + return makeEnumSetType(categories.primitives, hydrate); + }; + module.exports = makeEnum; +}); +/*can-query-logic@1.1.6#src/types/and-or-not-test*/ +define('can-query-logic@1.1.6#src/types/and-or-not-test', [ + 'require', + 'exports', + 'module', + './and-or-not', + 'steal-qunit', + '../set', + '../types/make-enum', + './comparisons' +], function (require, exports, module) { + var types = require('./and-or-not'); + var QUnit = require('steal-qunit'); + var set = require('../set'); + var makeEnum = require('../types/make-enum'); + var is = require('./comparisons'); + QUnit.module('can-query-logic/and-or'); + QUnit.test('AND intersection basics', function () { + var AndObject = types.KeysAnd; + var isJustin = new AndObject({ name: 'Justin' }); + var is35 = new AndObject({ age: 35 }); + var is35AndJustin = set.intersection(is35, isJustin); + QUnit.deepEqual(is35AndJustin.values, { + name: 'Justin', + age: 35 + }, '35 and justin'); + var isJustinAnd35 = set.intersection(isJustin, is35); + QUnit.deepEqual(isJustinAnd35.values, { + name: 'Justin', + age: 35 + }, 'justin and 34'); + var is34 = new AndObject({ age: 34 }); + is35 = new AndObject({ age: 35 }); + var is34and35 = set.intersection(is35, is34); + QUnit.equal(is34and35, set.EMPTY, 'can\'t be 34 and 35'); + }); + QUnit.test('AND union basics', function () { + var AndObject = types.KeysAnd; + var isJustin = new AndObject({ name: 'Justin' }); + var is35 = new AndObject({ age: 35 }); + var is35OrJustin = set.union(is35, isJustin); + QUnit.deepEqual(is35OrJustin, new types.ValuesOr([ + is35, + isJustin + ]), '35 and justin'); + }); + QUnit.test('AND / OR / NOT union', function () { + var isJustin = new types.KeysAnd({ name: 'Justin' }), isNotJustin = new types.KeysAnd({ name: new types.ValuesNot('Justin') }); + QUnit.equal(set.union(isJustin, isNotJustin), set.UNIVERSAL, '{name: \'j\'} U {name: NOT(\'j\')}'); + var everything = new types.KeysAnd({}); + QUnit.equal(set.union(isJustin, everything), set.UNIVERSAL, '{name: \'j\'} U {}'); + var isJustinAnd21 = new types.KeysAnd({ + name: 'Justin', + age: 22 + }); + QUnit.equal(set.union(isJustin, isJustinAnd21), isJustin, 'super and subset'); + QUnit.equal(set.union(isJustinAnd21, isJustinAnd21), isJustinAnd21, 'union with itself'); + }); + QUnit.test('AND / OR / NOT difference', function () { + var is35 = new types.KeysAnd({ age: 35 }), isJustin = new types.KeysAnd({ name: 'Justin' }), isJustinAnd35 = new types.KeysAnd({ + name: 'Justin', + age: 35 + }), isJustinAndNot35 = new types.KeysAnd({ + name: 'Justin', + age: new types.ValuesNot(35) + }), result; + result = set.difference(isJustin, is35); + QUnit.deepEqual(result, isJustinAndNot35, 'OVERLAP: {name: "Justin"} \\ {age: 35} -> {name: "justin", age: NOT(35)}'); + QUnit.deepEqual(set.difference(is35, is35), set.EMPTY, 'SAME SET: {age: 35} \\ {age: 35} -> EMPTY'); + QUnit.deepEqual(set.difference(isJustinAnd35, is35), set.EMPTY, 'SUPERSET: {age: 35, name: "Justin"} \\ {age: 35} -> EMPTY'); + QUnit.deepEqual(set.difference(isJustin, isJustinAnd35), isJustinAndNot35, '{name: "Justin"} \\ {age: 35, name: "Justin"} -> {name: "justin", age: NOT(35)}'); + result = set.difference(is35, new types.KeysAnd({ age: 32 })); + QUnit.deepEqual(result, new types.KeysAnd({ age: 35 }), 'DISJOINT: {age: 35} \\ {age: 32} -> {age: 35}'); + result = set.difference(new types.KeysAnd({ + age: 34, + name: 'Justin' + }), is35); + QUnit.deepEqual(result, new types.KeysAnd({ + age: 34, + name: 'Justin' + }), 'DISJOINT: {age: 34, name: "Justin"} \\ {age: 35} -> {age: 34, name: "Justin"}'); + result = set.difference(new types.KeysAnd({ foo: 'bar' }), isJustinAnd35); + QUnit.deepEqual(result, set.UNDEFINABLE, 'DISJOINT: {foo: "bar"} \\ {name: "Justin", age: 35} -> UNDEFINABLE'); + result = set.difference(set.UNIVERSAL, isJustinAnd35); + var compare = new types.ValuesOr([ + new types.KeysAnd({ name: new types.ValuesNot('Justin') }), + new types.KeysAnd({ age: new types.ValuesNot(35) }) + ]); + QUnit.deepEqual(result, compare, 'UNIVESAL: {} \\ {name: "Justin", age: 35} -> OR[ AND(name: NOT("Justin")), AND(age: NOT(35)) ]'); + result = set.difference(new types.KeysAnd({ foo: 2 }), new types.KeysAnd({ + foo: 2, + bar: set.UNIVERSAL + })); + QUnit.deepEqual(result, set.EMPTY, 'UNIVESAL: {foo:2} {foo:2, bar: IS_UNIVERSAL} -> set.EMPTY'); + }); + QUnit.test('AND / OR / NOT isSubset', function () { + var res; + res = set.isSubset(new types.KeysAnd({ type: 'FOLDER' }), new types.KeysAnd({ type: 'FOLDER' })); + QUnit.ok(res, 'equal sets'); + res = set.isSubset(new types.KeysAnd({ + type: 'FOLDER', + parentId: 5 + }), new types.KeysAnd({ type: 'FOLDER' })); + QUnit.ok(res, 'sub set'); + res = set.isSubset(new types.KeysAnd({ type: 'FOLDER' }), new types.KeysAnd({ + type: 'FOLDER', + parentId: 5 + })); + QUnit.notOk(res, 'wrong way'); + res = set.isSubset(new types.KeysAnd({ + type: 'FOLDER', + parentId: 7 + }), new types.KeysAnd({ + type: 'FOLDER', + parentId: 5 + })); + QUnit.ok(!res, 'different values'); + }); + QUnit.test('union AND with ENUM', function () { + function Color() { + } + var ColorSet = makeEnum(Color, [ + 'red', + 'green', + 'blue' + ]); + var qA = new types.KeysAnd({ + type: 'FOLDER', + status: new ColorSet('red') + }), qB = new types.KeysAnd({ + type: 'FOLDER', + status: new ColorSet('green') + }); + var res = set.union(qA, qB); + QUnit.deepEqual(res, new types.KeysAnd({ + type: 'FOLDER', + status: new ColorSet([ + 'red', + 'green' + ]) + }), 'able to do a union'); + }); + QUnit.test('AND isMember', function () { + var folderAnd35 = new types.KeysAnd({ + type: 'FOLDER', + age: 35 + }); + QUnit.ok(folderAnd35.isMember({ + type: 'FOLDER', + age: 35 + })); + QUnit.ok(folderAnd35.isMember({ + type: 'FOLDER', + age: 35, + extra: 'value' + })); + QUnit.notOk(folderAnd35.isMember({ + type: 'FOLDER', + age: 36 + })); + QUnit.notOk(folderAnd35.isMember({ + type: 'folder', + age: 35 + })); + QUnit.notOk(folderAnd35.isMember({ type: 'FOLDER' })); + QUnit.notOk(folderAnd35.isMember({ age: 35 })); + var isJustinPostCollege = new types.KeysAnd({ + name: { first: 'Justin' }, + age: 33 + }); + QUnit.ok(isJustinPostCollege.isMember({ + name: { + first: 'Justin', + last: 'Meyer' + }, + age: 33 + }), 'is member'); + }); + QUnit.test('OR isMember', function () { + var isFolder = new types.KeysAnd({ type: 'FOLDER' }), is35 = new types.KeysAnd({ age: 35 }), isFolderOr35 = new types.ValuesOr([ + isFolder, + is35 + ]); + QUnit.ok(isFolderOr35.isMember({ + type: 'FOLDER', + age: 35 + }), 'both'); + QUnit.notOk(isFolderOr35.isMember({}), 'empty'); + QUnit.ok(isFolderOr35.isMember({ + type: 'FOLDER', + age: 36 + })); + QUnit.ok(isFolderOr35.isMember({ + type: 'folder', + age: 35 + })); + QUnit.notOk(isFolderOr35.isMember({ + type: 'folder', + age: 36 + })); + QUnit.ok(isFolderOr35.isMember({ type: 'FOLDER' })); + QUnit.ok(isFolderOr35.isMember({ age: 35 })); + }); + QUnit.test('And nested objects', function () { + var res; + var isNameFirstJustin = new types.KeysAnd({ name: { first: 'Justin' } }); + var isNameFirstJustin2 = new types.KeysAnd({ name: { first: 'Justin' } }); + res = set.isEqual(isNameFirstJustin, isNameFirstJustin2); + QUnit.equal(res, true); + }); + QUnit.module('can-query-logic/not'); + QUnit.test('union basics', function () { + QUnit.equal(set.union(new types.ValuesNot(1), 1), set.UNIVERSAL, 'is univesal set'); + }); + QUnit.test('difference with universal', function () { + QUnit.equal(set.difference(new types.ValuesNot(1), set.UNIVERSAL), set.EMPTY, 'not 1 \\ univesal = 1'); + QUnit.deepEqual(set.difference(set.UNIVERSAL, 1), new types.ValuesNot(1), '1 \\ univesal = not 1'); + }); + QUnit.test('And with nested.properties', function () { + QUnit.equal(set.isSubset(new types.KeysAnd({ + 'name.first': 'Justin', + 'name.last': 'Meyer' + }), new types.KeysAnd({ 'name.last': 'Meyer' })), true, 'dot.ed properties work with subset'); + QUnit.equal(new types.KeysAnd({ + 'name.first': 'Justin', + 'name.last': 'Meyer' + }).isMember({ + name: { + first: 'Justin', + last: 'Meyer' + } + }), true, 'dot.ed properties isMember match'); + QUnit.equal(new types.KeysAnd({ + 'name.first': 'Justin', + 'name.last': 'Meyer' + }).isMember({ + name: { + first: 'Ramiya', + last: 'Meyer' + } + }), false, 'dot.ed properties isMember dont match'); + }); + QUnit.test('And with nested ands', function () { + QUnit.equal(set.isSubset(new types.KeysAnd({ + name: new types.KeysAnd({ + first: 'Justin', + last: 'Meyer' + }) + }), new types.KeysAnd({ name: new types.KeysAnd({ last: 'Meyer' }) })), true, 'properties work with subset'); + QUnit.deepEqual(set.intersection(new types.KeysAnd({ name: new types.KeysAnd({ first: 'Justin' }) }), new types.KeysAnd({ name: new types.KeysAnd({ last: 'Meyer' }) })), new types.KeysAnd({ + name: new types.KeysAnd({ + first: 'Justin', + last: 'Meyer' + }) + }), 'properties work with intersection'); + QUnit.equal(new types.KeysAnd({ + name: new types.KeysAnd({ + first: 'Justin', + last: 'Meyer' + }) + }).isMember({ + name: { + first: 'Justin', + last: 'Meyer' + } + }), true, 'dot.ed properties isMember match'); + QUnit.equal(new types.KeysAnd({ + name: new types.KeysAnd({ + first: 'Justin', + last: 'Meyer' + }) + }).isMember({ + name: { + first: 'Ramiya', + last: 'Meyer' + } + }), false, 'dot.ed properties isMember dont match'); + }); + QUnit.test('union with comparisons', function () { + var isGtJustinAndGt35 = new types.KeysAnd({ + name: new is.GreaterThan('Justin'), + age: new is.GreaterThan(35) + }); + var isGt25 = new types.KeysAnd({ age: new is.GreaterThan(25) }); + var result = set.union(isGtJustinAndGt35, isGt25); + QUnit.deepEqual(result, isGt25); + var a = new types.KeysAnd({ + name: new is.GreaterThan('Justin'), + age: new is.GreaterThan(35), + count: new is.GreaterThan(10) + }); + var b = new types.KeysAnd({ + age: new is.GreaterThan(25), + count: new is.GreaterThan(9) + }); + result = set.union(b, a); + QUnit.deepEqual(result, b); + }); +}); +/*can-query-logic@1.1.6#src/types/values-or-test*/ +define('can-query-logic@1.1.6#src/types/values-or-test', [ + 'require', + 'exports', + 'module', + './values-or', + './keys-and', + './comparisons' +], function (require, exports, module) { + var ValuesOr = require('./values-or'); + var KeysAnd = require('./keys-and'); + var valueIs = require('./comparisons'); +}); +/*can-query-logic@1.1.6#src/helpers*/ +define('can-query-logic@1.1.6#src/helpers', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + var canReflect = require('can-reflect'); + var typeNumber = { + 'undefined': 0, + 'null': 1, + 'number': 3, + 'string': 4, + 'object': 5, + 'boolean': 6 + }; + var getTypeNumber = function (obj) { + var type = typeof obj; + if (obj === null) { + type = 'null'; + } + return typeNumber[type]; + }; + var typeCompare = { + $gt: function (valueA, valueB) { + return getTypeNumber(valueA) > getTypeNumber(valueB); + }, + $lt: function (valueA, valueB) { + return getTypeNumber(valueA) < getTypeNumber(valueB); + } + }; + var defaultCompare = { + $gt: function (valueA, valueB) { + if (valueA == null || valueB == null) { + return typeCompare.$gt(valueA, valueB); + } + return valueA > valueB; + }, + $lt: function (valueA, valueB) { + if (valueA == null || valueB == null) { + return typeCompare.$gt(valueA, valueB); + } + return valueA < valueB; + } + }; + var helpers = { + uniqueConcat: function (itemsA, itemsB, getId) { + var ids = new Set(); + return itemsA.concat(itemsB).filter(function (item) { + var id = getId(item); + if (!ids.has(id)) { + ids.add(id); + return true; + } else { + return false; + } + }); + }, + getIndex: function (compare, items, props) { + if (!items || !items.length) { + return undefined; + } + if (compare(props, items[0]) === -1) { + return 0; + } else if (compare(props, items[items.length - 1]) === 1) { + return items.length; + } + var low = 0, high = items.length; + while (low < high) { + var mid = low + high >>> 1, item = items[mid], computed = compare(props, item); + if (computed === -1) { + high = mid; + } else { + low = mid + 1; + } + } + return high; + }, + sortData: function (sortPropValue) { + if (sortPropValue[0] === '-') { + return { + prop: sortPropValue.slice(1), + desc: true + }; + } else { + return { + prop: sortPropValue, + desc: false + }; + } + }, + defaultCompare: defaultCompare, + typeCompare: typeCompare, + sorter: function (sortPropValue, sorters) { + var data = helpers.sortData(sortPropValue); + var compare; + if (sorters && sorters[data.prop]) { + compare = sorters[data.prop]; + } else { + compare = defaultCompare; + } + return function (item1, item2) { + var item1Value = canReflect.getKeyValue(item1, data.prop); + var item2Value = canReflect.getKeyValue(item2, data.prop); + var temp; + if (data.desc) { + temp = item1Value; + item1Value = item2Value; + item2Value = temp; + } + if (compare.$lt(item1Value, item2Value)) { + return -1; + } + if (compare.$gt(item1Value, item2Value)) { + return 1; + } + return 0; + }; + }, + valueHydrator: function (value) { + if (canReflect.isBuiltIn(value)) { + return value; + } else { + throw new Error('can-query-logic doesn\'t support comparison operator: ' + JSON.stringify(value)); + } + } + }; + module.exports = helpers; +}); +/*can-query-logic@1.1.6#src/types/basic-query*/ +define('can-query-logic@1.1.6#src/types/basic-query', [ + 'require', + 'exports', + 'module', + '../set', + './make-real-number-range-inclusive', + 'can-assign', + 'can-reflect', + './and-or-not', + '../helpers', + 'can-define-lazy-value', + 'can-symbol' +], function (require, exports, module) { + var set = require('../set'); + var makeRealNumberRangeInclusive = require('./make-real-number-range-inclusive'); + var assign = require('can-assign'); + var canReflect = require('can-reflect'); + var andOrNot = require('./and-or-not'); + var helpers = require('../helpers'); + var defineLazyValue = require('can-define-lazy-value'); + var canSymbol = require('can-symbol'); + var isMemberSymbol = canSymbol.for('can.isMember'); + var KeysAnd = andOrNot.KeysAnd, Or = andOrNot.ValuesOr, Not = andOrNot.ValuesNot; + var RecordRange = makeRealNumberRangeInclusive(0, Infinity); + function makeSort(schemaKeys, hydrateAndValue) { + var sorters = {}; + canReflect.eachKey(schemaKeys, function (schemaProp, key) { + sorters[key] = { + $gt: function (valueA, valueB) { + if (valueA == null || valueB == null) { + return helpers.typeCompare.$gt(valueA, valueB); + } + var $gt = hydrateAndValue({ $gt: valueB }, key, schemaProp, helpers.valueHydrator); + return $gt[isMemberSymbol](valueA); + }, + $lt: function (valueA, valueB) { + if (valueA == null || valueB == null) { + return helpers.typeCompare.$lt(valueA, valueB); + } + var $lt = hydrateAndValue({ $lt: valueB }, key, schemaProp, helpers.valueHydrator); + return $lt[isMemberSymbol](valueA); + } + }; + }); + function Sort(key) { + this.key = key; + this.compare = helpers.sorter(key, sorters); + } + function identityIntersection(v1, v2) { + return v1.key === v2.key ? v1 : set.EMPTY; + } + function identityDifference(v1, v2) { + return v1.key === v2.key ? set.EMPTY : v1; + } + function identityUnion(v1, v2) { + return v1.key === v2.key ? v1 : set.UNDEFINABLE; + } + set.defineComparison(Sort, Sort, { + intersection: identityIntersection, + difference: identityDifference, + union: identityUnion + }); + return Sort; + } + var DefaultSort = makeSort({}); + function BasicQuery(query) { + assign(this, query); + if (!this.filter) { + this.filter = set.UNIVERSAL; + } + if (!this.page) { + this.page = new RecordRange(); + } + if (!this.sort) { + this.sort = 'id'; + } + if (typeof this.sort === 'string') { + this.sort = new DefaultSort(this.sort); + } + } + BasicQuery.KeysAnd = KeysAnd; + BasicQuery.Or = Or; + BasicQuery.Not = Not; + BasicQuery.RecordRange = RecordRange; + BasicQuery.makeSort = makeSort; + canReflect.assignMap(BasicQuery.prototype, { + count: function () { + return this.page.end - this.page.start + 1; + }, + sortData: function (data) { + return data.slice(0).sort(this.sort.compare); + }, + filterMembersAndGetCount: function (bData, parentQuery) { + if (parentQuery) { + if (!set.isSubset(this, parentQuery)) { + throw new Error('can-query-logic: Unable to get members from a set that is not a superset of the current set.'); + } + } else { + parentQuery = new BasicQuery(); + } + var aData = bData.filter(function (data) { + return this.filter.isMember(data); + }, this); + var count = aData.length; + if (count && this.sort.key !== parentQuery.sort.key) { + aData = this.sortData(aData); + } + var thisIsUniversal = set.isEqual(this.page, set.UNIVERSAL), parentIsUniversal = set.isEqual(parentQuery.page, set.UNIVERSAL); + if (parentIsUniversal) { + if (thisIsUniversal) { + return { + data: aData, + count: count + }; + } else { + return { + data: aData.slice(this.page.start, this.page.end + 1), + count: count + }; + } + } else if (this.sort.key === parentQuery.sort.key && set.isEqual(parentQuery.filter, this.filter)) { + return { + data: aData.slice(this.page.start - parentQuery.page.start, this.page.end - parentQuery.page.start + 1), + count: count + }; + } else { + throw new Error('can-query-logic: Unable to get members from the parent set for this subset.'); + } + }, + filterFrom: function (bData, parentQuery) { + return this.filterMembersAndGetCount(bData, parentQuery).data; + }, + merge: function (b, aItems, bItems, getId) { + var union = set.union(this, b); + if (union === set.UNDEFINABLE) { + return undefined; + } else { + var combined = helpers.uniqueConcat(aItems, bItems, getId); + return union.sortData(combined); + } + }, + index: function (props, items) { + var data = helpers.sortData(this.sort.key); + if (!canReflect.hasOwnKey(props, data.prop)) { + return undefined; + } + return helpers.getIndex(this.sort.compare, items, props); + }, + isMember: function (props) { + return this.filter.isMember(props); + }, + removePagination: function () { + this.page = new RecordRange(); + } + }); + var CLAUSE_TYPES = [ + 'filter', + 'page', + 'sort' + ]; + function getDifferentClauseTypes(queryA, queryB) { + var differentTypes = []; + CLAUSE_TYPES.forEach(function (clause) { + if (!set.isEqual(queryA[clause], queryB[clause])) { + differentTypes.push(clause); + } + }); + return differentTypes; + } + function isSubset(subLetter, superLetter, meta) { + if (meta[subLetter + 'FilterIsSubset']) { + if (meta[superLetter + 'PageIsUniversal']) { + return true; + } else { + return meta[subLetter + 'PageIsSubset'] && meta.sortIsEqual; + } + } else { + return false; + } + } + function MetaInformation(queryA, queryB) { + this.queryA = queryA; + this.queryB = queryB; + } + canReflect.eachKey({ + 'pageIsEqual': function () { + return set.isEqual(this.queryA.page, this.queryB.page); + }, + 'aPageIsUniversal': function () { + return set.isEqual(this.queryA.page, set.UNIVERSAL); + }, + 'bPageIsUniversal': function () { + return set.isEqual(this.queryB.page, set.UNIVERSAL); + }, + 'pagesAreUniversal': function () { + return this.pageIsEqual && this.aPageIsUniversal; + }, + 'sortIsEqual': function () { + return this.queryA.sort.key === this.queryB.sort.key; + }, + 'aFilterIsSubset': function () { + return set.isSubset(this.queryA.filter, this.queryB.filter); + }, + 'bFilterIsSubset': function () { + return set.isSubset(this.queryB.filter, this.queryA.filter); + }, + 'aPageIsSubset': function () { + return set.isSubset(this.queryA.page, this.queryB.page); + }, + 'bPageIsSubset': function () { + return set.isSubset(this.queryB.page, this.queryA.page); + }, + 'filterIsEqual': function () { + return set.isEqual(this.queryA.filter, this.queryB.filter); + }, + 'aIsSubset': function () { + return isSubset('a', 'b', this); + }, + 'bIsSubset': function () { + return isSubset('b', 'a', this); + } + }, function (def, prop) { + defineLazyValue(MetaInformation.prototype, prop, def); + }); + function metaInformation(queryA, queryB) { + var meta = new MetaInformation(queryA, queryB); + return meta; + } + set.defineComparison(BasicQuery, BasicQuery, { + union: function (queryA, queryB) { + var meta = metaInformation(queryA, queryB); + var filterUnion = set.union(queryA.filter, queryB.filter); + if (meta.pagesAreUniversal) { + return new BasicQuery({ + filter: filterUnion, + sort: meta.sortIsEqual ? queryA.sort.key : undefined + }); + } + if (meta.filterIsEqual) { + if (meta.sortIsEqual) { + return new BasicQuery({ + filter: queryA.filter, + sort: queryA.sort.key, + page: set.union(queryA.page, queryB.page) + }); + } else { + if (meta.aIsSubset) { + return queryB; + } else if (meta.bIsSubset) { + return queryA; + } + return set.UNDEFINABLE; + } + } else { + throw new Error('different filters, non-universal pages'); + } + }, + intersection: function (queryA, queryB) { + var meta = metaInformation(queryA, queryB); + if (meta.pagesAreUniversal) { + var filterResult = set.intersection(queryA.filter, queryB.filter); + if (set.isDefinedAndHasMembers(filterResult)) { + return new BasicQuery({ + filter: filterResult, + sort: meta.sortIsEqual ? queryA.sort.key : undefined + }); + } else { + return filterResult; + } + } + if (set.intersection(queryA.filter, queryB.filter) === set.EMPTY) { + return set.EMPTY; + } + if (meta.filterIsEqual) { + if (meta.sortIsEqual) { + return new BasicQuery({ + filter: queryA.filter, + sort: queryA.sort.key, + page: set.intersection(queryA.page, queryB.page) + }); + } else { + if (meta.aIsSubset) { + return queryA; + } else if (meta.bIsSubset) { + return queryB; + } + return set.UNKNOWABLE; + } + } else { + if (meta.aIsSubset) { + return queryA; + } else if (meta.bIsSubset) { + return queryB; + } else { + return set.UNDEFINABLE; + } + } + }, + difference: function (queryA, queryB) { + var differentClauses = getDifferentClauseTypes(queryA, queryB); + var meta = metaInformation(queryA, queryB); + var clause; + if (differentClauses.length > 1) { + if (meta.aIsSubset) { + return set.EMPTY; + } + if (meta.pagesAreUniversal) { + return new BasicQuery({ + filter: set.difference(queryA.filter, queryB.filter), + sort: queryA.sort.key + }); + } + return set.UNDEFINABLE; + } else { + switch (clause = differentClauses[0]) { + case undefined: { + return set.EMPTY; + } + case 'sort': { + if (meta.pagesAreUniversal) { + return set.EMPTY; + } else { + return set.UNKNOWABLE; + } + } + case 'page': + case 'filter': { + var result = set.difference(queryA[clause], queryB[clause]); + if (set.isSpecial(result)) { + return result; + } else { + var query = { + filter: queryA.filter, + page: queryA.page, + sort: queryA.sort.key + }; + query[clause] = result; + return new BasicQuery(query); + } + } + } + } + } + }); + module.exports = BasicQuery; +}); +/*can-query-logic@1.1.6#src/types/basic-query-sorting-test*/ +define('can-query-logic@1.1.6#src/types/basic-query-sorting-test', [ + 'require', + 'exports', + 'module', + './basic-query', + 'steal-qunit', + '../set', + 'can-assign', + 'can-reflect' +], function (require, exports, module) { + var BasicQuery = require('./basic-query'); + var QUnit = require('steal-qunit'); + var set = require('../set'); + var assign = require('can-assign'); + var canReflect = require('can-reflect'); + QUnit.module('can-query-logic/types/basic-query sorting'); + function legacyToQuery(set) { + var copy = assign({}, set); + var page = new BasicQuery.RecordRange(copy.start || 0, copy.end || Infinity); + delete copy.start; + delete copy.end; + return new BasicQuery({ + page: page, + filter: Object.keys(copy).length ? new BasicQuery.KeysAnd(copy) : set.UNIVERSAL + }); + } + function queryToLegacy(query) { + var legacy = {}; + if (query.page) { + if (set.isEqual(query.page, set.UNIVERSAL)) { + } else { + legacy.start = query.page.start; + legacy.end = query.page.end; + } + } + return legacy; + } + function legacyIsEqual(setA, setB) { + var qA = legacyToQuery(setA), qB = legacyToQuery(setB); + return set.isEqual(qA, qB); + } + function legacyDifference(setA, setB) { + var qA = legacyToQuery(setA), qB = legacyToQuery(setB); + return queryToLegacy(set.difference(qA, qB)); + } + function legacyIntersection(setA, setB) { + var qA = legacyToQuery(setA), qB = legacyToQuery(setB); + return queryToLegacy(set.intersection(qA, qB)); + } + function legacyUnion(setA, setB) { + var qA = legacyToQuery(setA), qB = legacyToQuery(setB); + return queryToLegacy(set.union(qA, qB)); + } + function legacySubset(setA, setB) { + var qA = legacyToQuery(setA), qB = legacyToQuery(setB); + return set.isSubset(qA, qB); + } + test('rangeInclusive legacyDifference', function () { + var res = legacyDifference({ + start: 0, + end: 99 + }, { + start: 50, + end: 101 + }); + deepEqual(res, { + start: 0, + end: 49 + }, 'got a diff'); + res = legacyDifference({}, { + start: 0, + end: 10 + }); + deepEqual(res, { + start: 11, + end: Infinity + }, 'universal set'); + res = legacyDifference({ + start: 0, + end: 49 + }, { + start: 50, + end: 101 + }); + deepEqual(res, { + start: 0, + end: 49 + }, 'side by side'); + res = legacyDifference({ + start: 0, + end: 49 + }, { + start: 0, + end: 20 + }); + deepEqual(res, { + start: 21, + end: 49 + }, 'first set extends past second'); + res = legacyDifference({ + start: 0, + end: 49 + }, { + start: 20, + end: 49 + }); + deepEqual(res, { + start: 0, + end: 19 + }, 'first set starts before second'); + }); + test('rangeInclusive legacyIntersection', function () { + var res = legacyIntersection({ + start: 0, + end: 99 + }, { + start: 50, + end: 101 + }); + deepEqual(res, { + start: 50, + end: 99 + }, 'got a intersection'); + }); + test('rangeInclusive legacyIsEqual', function () { + ok(!legacyIsEqual({ + start: 0, + end: 100 + }, { + start: 0, + end: 101 + }), 'they are not equal'); + ok(!legacyIsEqual({ + start: 0, + end: 100 + }, { + start: 1, + end: 100 + }), 'they are not equal'); + }); + test('rangeInclusive legacySubset', function () { + ok(legacySubset({ + start: 0, + end: 100 + }, { + start: 0, + end: 100 + }), 'self is a subset'); + ok(legacySubset({ + start: 0, + end: 100 + }, { + start: 0, + end: 101 + }), 'end extends past subset'); + QUnit.equal(legacySubset({ + start: 0, + end: 101 + }, { + start: 0, + end: 100 + }), false, 'non-subset extends past end'); + ok(legacySubset({ + start: 1, + end: 100 + }, { + start: 0, + end: 100 + }), 'start extends before subset'); + ok(!legacySubset({ + start: 0, + end: 100 + }, { + start: 1, + end: 100 + }), 'non-subset extends before start'); + }); + test('rangeInclusive legacyUnion', function () { + res = legacyUnion({}, { + start: 0, + end: 10 + }); + deepEqual(res, {}, 'universal set'); + return; + res = legacyUnion({ + start: 100, + end: 199 + }, { + start: 200, + end: 299 + }); + deepEqual(res, { + start: 100, + end: 299 + }, 'no intersection'); + res = legacyUnion({ + start: 200, + end: 299 + }, { + start: 100, + end: 199 + }); + deepEqual(res, { + start: 100, + end: 299 + }, 'no intersection with either argument order'); + res = legacyUnion({ + start: 200, + end: 299 + }, { + start: 100, + end: 209 + }); + deepEqual(res, { + start: 100, + end: 299 + }, 'sets can intersect'); + res = legacyUnion({ + start: 100, + end: 209 + }, { + start: 200, + end: 299 + }); + deepEqual(res, { + start: 100, + end: 299 + }, 'sets can intersect with either argument order'); + res = legacyUnion({ + start: 100, + end: 299 + }, { + start: 103, + end: 209 + }); + deepEqual(res, { + start: 100, + end: 299 + }, 'first set contains second'); + res = legacyUnion({ + start: 100, + end: 299 + }, { + start: 103, + end: 209 + }); + deepEqual(res, { + start: 100, + end: 299 + }, 'second set contains first'); + res = legacyUnion({ + start: 100, + end: 299 + }, { + start: 100, + end: 299 + }); + deepEqual(res, { + start: 100, + end: 299 + }, 'union of identical sets is the same as those sets'); + }); + QUnit.test('rangeInclusive set.count', function () { + var query = new BasicQuery({ + page: new BasicQuery.RecordRange(0, 99), + filter: set.UNIVERSAL + }); + var res = query.count({ + start: 0, + end: 99 + }); + equal(res, 100, 'count is right'); + }); + QUnit.test('index uses can-reflect', function () { + var query = new BasicQuery({ sort: 'name' }); + var obj1Read, obj2Read, itemKeyRead, itemOwnKeyRead; + var obj1 = canReflect.assignSymbols({}, { + 'can.getKeyValue': function (key) { + obj1Read = true; + return { + id: 5, + name: 'x' + }[key]; + } + }), obj2 = canReflect.assignSymbols({}, { + 'can.getKeyValue': function (key) { + obj2Read = true; + return { + id: 7, + name: 'd' + }[key]; + } + }), item = canReflect.assignSymbols({}, { + 'can.getKeyValue': function (key) { + itemKeyRead = true; + return { + id: 1, + name: 'j' + }[key]; + }, + 'can.hasOwnKey': function (key) { + itemOwnKeyRead = true; + return key in { + id: 1, + name: 'j' + }; + } + }); + var res = query.index(item, [ + obj2, + obj1 + ]); + QUnit.equal(res, 1, 'inserted at 1'); + QUnit.deepEqual([ + obj1Read, + obj2Read, + itemKeyRead, + itemOwnKeyRead + ], [ + true, + true, + true, + true + ], 'read everything'); + }); +}); +/*can-query-logic@1.1.6#src/types/basic-query-filter-from-test*/ +define('can-query-logic@1.1.6#src/types/basic-query-filter-from-test', [ + 'require', + 'exports', + 'module', + './basic-query', + 'steal-qunit' +], function (require, exports, module) { + var BasicQuery = require('./basic-query'); + var QUnit = require('steal-qunit'); + QUnit.module('can-query-logic/types/basic-query filterFrom'); + var getId = function (d) { + return d.id; + }; + var items = [ + { + id: 0, + note: 'C', + type: 'eh' + }, + { + id: 1, + note: 'D', + type: 'critical' + }, + { + id: 2, + note: 'E', + type: 'critical' + }, + { + id: 3, + note: 'F', + type: 'eh' + }, + { + id: 4, + note: 'G', + type: 'critical' + }, + { + id: 5, + note: 'A' + }, + { + id: 6, + note: 'B', + type: 'critical' + }, + { + id: 7, + note: 'C', + type: 'critical' + } + ]; + QUnit.test('against non ranged set', function () { + var query = new BasicQuery({ + filter: new BasicQuery.KeysAnd({ type: 'critical' }), + page: new BasicQuery.RecordRange(1, 3) + }); + var res = query.filterFrom(items); + QUnit.deepEqual(res && res.map(getId), [ + 2, + 4, + 6 + ]); + }); + QUnit.test('ordered ascending and paginated', function () { + var query = new BasicQuery({ + filter: new BasicQuery.KeysAnd({ type: 'critical' }), + page: new BasicQuery.RecordRange(1, 3), + sort: 'note' + }); + var res = query.filterFrom(items); + QUnit.deepEqual(res && res.map(getId), [ + 7, + 1, + 2 + ]); + }); + QUnit.test('ordered descending and paginated', function () { + var query = new BasicQuery({ + filter: new BasicQuery.KeysAnd({ type: 'critical' }), + page: new BasicQuery.RecordRange(1, 3), + sort: '-note' + }); + var res = query.filterFrom(items); + QUnit.deepEqual(res && res.map(getId), [ + 2, + 1, + 7 + ]); + }); + QUnit.test('against paginated set', function () { + var query = new BasicQuery({ + filter: new BasicQuery.KeysAnd({ type: 'critical' }), + page: new BasicQuery.RecordRange(21, 23) + }); + var fromQuery = new BasicQuery({ + filter: new BasicQuery.KeysAnd({ type: 'critical' }), + page: new BasicQuery.RecordRange(20, 27) + }); + var res = query.filterFrom(items, fromQuery); + QUnit.deepEqual(res && res.map(getId), [ + 2, + 4, + 6 + ]); + }); + QUnit.test('returns undefined against incompatible set', function () { + var query = new BasicQuery({ filter: new BasicQuery.KeysAnd({ note: 'C' }) }); + var fromQuery = new BasicQuery({ filter: new BasicQuery.KeysAnd({ type: 'critical' }) }); + try { + var res = query.filterFrom(items, fromQuery); + } catch (e) { + QUnit.ok(true, 'throws an error'); + } + }); +}); +/*can-query-logic@1.1.6#src/types/basic-query-merge-test*/ +define('can-query-logic@1.1.6#src/types/basic-query-merge-test', [ + 'require', + 'exports', + 'module', + './basic-query', + 'steal-qunit' +], function (require, exports, module) { + var BasicQuery = require('./basic-query'); + var QUnit = require('steal-qunit'); + QUnit.module('can-query-logic/types/basic-query merge'); + var getId = function (d) { + return d.id; + }; + var items = [ + { + id: 0, + note: 'C', + type: 'eh' + }, + { + id: 1, + note: 'D', + type: 'critical' + }, + { + id: 2, + note: 'E', + type: 'critical' + }, + { + id: 3, + note: 'F', + type: 'eh' + }, + { + id: 4, + note: 'G', + type: 'critical' + }, + { + id: 5, + note: 'A' + }, + { + id: 6, + note: 'B', + type: 'critical' + }, + { + id: 7, + note: 'C', + type: 'critical' + } + ]; + var everything = new BasicQuery({}); + QUnit.test('basics', function () { + var fooBar = new BasicQuery({ filter: new BasicQuery.KeysAnd({ foo: 'bar' }) }); + var res = everything.merge(fooBar, items, items.slice(0, 3), getId); + deepEqual(res, items); + }); + QUnit.test('unionMembers against ranged sets', function () { + var a = new BasicQuery({ page: new BasicQuery.RecordRange(10, 13) }); + var b = new BasicQuery({ page: new BasicQuery.RecordRange(10, 13) }); + var union = a.merge(b, items.slice(0, 4), items.slice(4, 8), getId); + a = new BasicQuery({ page: new BasicQuery.RecordRange(14, 17) }); + union = a.merge(b, items.slice(4, 8), items.slice(0, 4), getId); + deepEqual(union, items, 'disjoint after'); + }); + QUnit.test('unionMembers against overlapping ranged sets', function () { + var a = new BasicQuery({ page: new BasicQuery.RecordRange(10, 13) }); + var b = new BasicQuery({ page: new BasicQuery.RecordRange(13, 17) }); + var union = a.merge(b, items.slice(0, 5), items.slice(3, 8), getId); + deepEqual(union, items); + a = new BasicQuery({ page: new BasicQuery.RecordRange(10, 11) }); + b = new BasicQuery({ page: new BasicQuery.RecordRange(11, 17) }); + union = a.merge(b, items.slice(0, 2), items.slice(1, 8), getId); + deepEqual(union, items); + a = new BasicQuery({ page: new BasicQuery.RecordRange(10, 11) }); + b = new BasicQuery({ page: new BasicQuery.RecordRange(11, 17) }); + union = b.merge(a, items.slice(1, 8), items.slice(0, 2), getId); + deepEqual(union, items); + }); + QUnit.test('unionMembers filters for uniqueness', function () { + var aItems = items.filter(function (a) { + return a.type === 'critical'; + }); + var bItems = items.filter(function (b) { + return b.note === 'C'; + }); + var unionItems = [bItems[0]].concat(aItems); + var a = new BasicQuery({ page: new BasicQuery.KeysAnd({ type: 'critical' }) }); + var b = new BasicQuery({ page: new BasicQuery.KeysAnd({ note: 'C' }) }); + var union = a.merge(b, aItems, bItems, getId); + deepEqual(union, unionItems); + var union = b.merge(a, bItems, aItems, getId); + deepEqual(union, unionItems); + }); +}); +/*can-query-logic@1.1.6#src/serializer*/ +define('can-query-logic@1.1.6#src/serializer', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + var canReflect = require('can-reflect'); + var Serializer = function (entries) { + var serializers = this.serializers = new Map(); + if (entries) { + entries.forEach(function (entry) { + var key = entry[0], value = entry[1]; + serializers.set(key, value); + }); + } + this.serialize = this.serialize.bind(this); + }; + Serializer.prototype.add = function (serializers) { + canReflect.assign(this.serializers, serializers instanceof Serializer ? serializers.serializers : serializers); + }; + Serializer.prototype.serialize = function (item) { + if (!item) { + return item; + } + var Type = item.constructor; + var serializer = this.serializers.get(Type); + if (!serializer) { + return canReflect.serialize(item); + } else { + return serializer(item, this.serialize); + } + }; + module.exports = Serializer; +}); +/*can-query-logic@1.1.6#src/serializers/comparisons*/ +define('can-query-logic@1.1.6#src/serializers/comparisons', [ + 'require', + 'exports', + 'module', + '../types/comparisons', + '../serializer', + 'can-reflect' +], function (require, exports, module) { + var is = require('../types/comparisons'); + var Serializer = require('../serializer'); + var canReflect = require('can-reflect'); + function makeNew(Constructor) { + return function (value) { + return new Constructor(value); + }; + } + var hydrateMap = {}; + function addHydrateFrom(key, hydrate) { + hydrateMap[key] = function (value, unknownHydrator) { + return hydrate(unknownHydrator ? unknownHydrator(value[key]) : value[key]); + }; + Object.defineProperty(hydrateMap[key], 'name', { + value: 'hydrate ' + key, + writable: true + }); + } + function addHydrateFromValues(key, hydrate) { + hydrateMap[key] = function (value, unknownHydrator) { + var clones = value[key]; + if (unknownHydrator) { + clones = clones.map(function (value) { + return unknownHydrator(value); + }); + } + return hydrate(clones); + }; + Object.defineProperty(hydrateMap[key], 'name', { + value: 'hydrate ' + key, + writable: true + }); + } + addHydrateFrom('$eq', function (value) { + return new is.In([value]); + }); + addHydrateFrom('$ne', function (value) { + return new is.NotIn([value]); + }); + addHydrateFrom('$gt', makeNew(is.GreaterThan)); + addHydrateFrom('$gte', makeNew(is.GreaterThanEqual)); + addHydrateFromValues('$in', makeNew(is.In)); + addHydrateFrom('$lt', makeNew(is.LessThan)); + addHydrateFrom('$lte', makeNew(is.LessThanEqual)); + addHydrateFromValues('$nin', makeNew(is.GreaterThan)); + var serializer = new Serializer([ + [ + is.In, + function (isIn, serialize) { + return isIn.values.length === 1 ? serialize(isIn.values[0]) : { $in: isIn.values.map(serialize) }; + } + ], + [ + is.NotIn, + function (notIn, serialize) { + return notIn.values.length === 1 ? { $ne: serialize(notIn.values[0]) } : { $nin: notIn.values.map(serialize) }; + } + ], + [ + is.GreaterThan, + function (gt, serialize) { + return { $gt: serialize(gt.value) }; + } + ], + [ + is.GreaterThanEqual, + function (gte, serialize) { + return { $gte: serialize(gte.value) }; + } + ], + [ + is.LessThan, + function (lt, serialize) { + return { $lt: serialize(lt.value) }; + } + ], + [ + is.LessThanEqual, + function (lt, serialize) { + return { $lte: serialize(lt.value) }; + } + ], + [ + is.And, + function (and, serialize) { + var obj = {}; + and.values.forEach(function (clause) { + canReflect.assignMap(obj, serialize(clause)); + }); + return obj; + } + ] + ]); + module.exports = { + hydrate: function (value, hydrateUnknown) { + if (!hydrateUnknown) { + hydrateUnknown = function () { + throw new Error('can-query-logic doesn\'t recognize operator: ' + JSON.stringify(value)); + }; + } + if (Array.isArray(value)) { + return new is.In(value.map(function (value) { + return hydrateUnknown(value); + })); + } else if (value && typeof value === 'object') { + var keys = Object.keys(value); + var allKeysAreComparisons = keys.every(function (key) { + return hydrateMap[key]; + }); + if (allKeysAreComparisons) { + var andClauses = keys.map(function (key) { + var part = {}; + part[key] = value[key]; + var hydrator = hydrateMap[key]; + return hydrator(part, hydrateUnknown); + }); + if (andClauses.length > 1) { + return new is.And(andClauses); + } else { + return andClauses[0]; + } + } else { + return hydrateUnknown(value); + } + } else { + return new is.In([hydrateUnknown(value)]); + } + }, + serializer: serializer + }; +}); +/*can-query-logic@1.1.6#src/types/make-maybe*/ +define('can-query-logic@1.1.6#src/types/make-maybe', [ + 'require', + 'exports', + 'module', + '../set', + './comparisons', + 'can-reflect', + '../schema-helpers', + 'can-symbol' +], function (require, exports, module) { + var set = require('../set'); + var is = require('./comparisons'); + var canReflect = require('can-reflect'); + var schemaHelpers = require('../schema-helpers'); + var canSymbol = require('can-symbol'); + var comparisonSetTypeSymbol = canSymbol.for('can.ComparisonSetType'); + var isMemberSymbol = canSymbol.for('can.isMember'); + function splitByRangeAndEnum(maybeUniverse, rangeToBeSplit) { + var enumSet; + if (rangeToBeSplit instanceof is.And) { + var sets = rangeToBeSplit.values.map(function (setInAnd) { + return splitByRangeAndEnum(maybeUniverse, setInAnd); + }); + return sets.reduce(function (last, maybe) { + return { + range: set.intersection(last.range, maybe.range), + enum: set.intersection(last.enum, maybe.enum) + }; + }, { + range: set.UNIVERSAL, + enum: maybeUniverse + }); + } else if (rangeToBeSplit instanceof is.In) { + var shouldBeInValues = rangeToBeSplit.values.filter(function (value) { + return maybeUniverse.isMember(value); + }); + if (shouldBeInValues.length) { + var valuesCopy = rangeToBeSplit.values.slice(0); + canReflect.removeValues(valuesCopy, shouldBeInValues); + return { + enum: new is.In(shouldBeInValues), + range: valuesCopy.length ? new is.In(valuesCopy) : set.EMPTY + }; + } else { + return { + enum: set.EMPTY, + range: rangeToBeSplit + }; + } + } else if (rangeToBeSplit instanceof is.NotIn) { + enumSet = set.intersection(maybeUniverse, rangeToBeSplit); + var rangeValues = rangeToBeSplit.values.filter(function (value) { + return !maybeUniverse.isMember(value); + }); + return { + range: rangeValues.length ? new is.NotIn(rangeValues) : set.UNIVERSAL, + enum: enumSet + }; + } else { + return { + enum: set.EMPTY, + range: rangeToBeSplit + }; + } + } + function makeMaybe(inValues, makeChildType) { + var maybeUniverse = new is.In(inValues); + function Maybe(values) { + var result = splitByRangeAndEnum(maybeUniverse, values.range); + this.range = result.range || set.EMPTY; + if (values.enum) { + if (result.enum !== set.EMPTY) { + this.enum = set.union(result.enum, values.enum); + } else { + this.enum = values.enum; + } + } else { + this.enum = result.enum; + } + if (this.enum === set.EMPTY && this.range === set.EMPTY) { + return set.EMPTY; + } + } + Maybe.prototype.orValues = function () { + var values = []; + if (this.range !== set.EMPTY) { + values.push(this.range); + } + if (this.enum !== set.EMPTY) { + values.push(this.enum); + } + return values; + }; + Maybe.prototype[isMemberSymbol] = function isMember() { + var rangeIsMember = this.range[isMemberSymbol] || this.range.isMember, enumIsMember = this.enum[isMemberSymbol] || this.enum.isMember; + return rangeIsMember.apply(this.range, arguments) || enumIsMember.apply(this.enum, arguments); + }; + set.defineComparison(Maybe, Maybe, { + union: function (maybeA, maybeB) { + var enumSet = set.union(maybeA.enum, maybeB.enum); + var range = set.union(maybeA.range, maybeB.range); + return new Maybe({ + enum: enumSet, + range: range + }); + }, + difference: function (maybeA, maybeB) { + var enumSet = set.difference(maybeA.enum, maybeB.enum); + var range = set.difference(maybeA.range, maybeB.range); + return new Maybe({ + enum: enumSet, + range: range + }); + }, + intersection: function (maybeA, maybeB) { + var enumSet = set.intersection(maybeA.enum, maybeB.enum); + var range = set.intersection(maybeA.range, maybeB.range); + return new Maybe({ + enum: enumSet, + range: range + }); + } + }); + Maybe.inValues = inValues; + set.defineComparison(set.UNIVERSAL, Maybe, { + difference: function (universe, maybe) { + var primary, secondary; + if (maybe.range === set.UNIVERSAL) { + return new Maybe({ + range: maybe.range, + enum: set.difference(maybeUniverse, maybe.enum) + }); + } + if (maybe.enum === set.EMPTY) { + var rangeSet = set.difference(set.UNIVERSAL, maybe.range); + var notPresent = set.difference(maybeUniverse, maybe.range); + var enumSet = set.difference(notPresent, rangeSet); + return new Maybe({ + range: rangeSet, + enum: enumSet + }); + } else { + primary = set.difference(universe, maybe.range); + secondary = set.difference(maybeUniverse, maybe.enum); + } + return new Maybe({ + enum: secondary, + range: primary + }); + } + }); + makeChildType = makeChildType || function (v) { + return v; + }; + Maybe.hydrate = function (value, childHydrate) { + return new Maybe({ range: childHydrate(value, makeChildType) }); + }; + return Maybe; + } + makeMaybe.canMakeMaybeSetType = function (Type) { + var schema = canReflect.getSchema(Type); + if (schema && schema.type === 'Or') { + var categories = schemaHelpers.categorizeOrValues(schema.values); + return categories.valueOfTypes.length === 1 && categories.valueOfTypes.length + categories.primitives.length === schema.values.length; + } + return false; + }; + makeMaybe.makeMaybeSetTypes = function (Type) { + var schema = canReflect.getSchema(Type); + var categories = schemaHelpers.categorizeOrValues(schema.values); + var ComparisonSetType; + if (Type[comparisonSetTypeSymbol]) { + ComparisonSetType = Type[comparisonSetTypeSymbol]; + } else { + ComparisonSetType = function (value) { + this.value = canReflect.new(Type, value); + }; + ComparisonSetType.prototype.valueOf = function () { + return this.value; + }; + canReflect.assignSymbols(ComparisonSetType.prototype, { + 'can.serialize': function () { + return this.value; + } + }); + } + return { + Maybe: makeMaybe(categories.primitives, function hydrateMaybesValueType(value) { + return new ComparisonSetType(value); + }), + ComparisonSetType: ComparisonSetType + }; + }; + module.exports = makeMaybe; +}); +/*can-query-logic@1.1.6#src/serializers/basic-query*/ +define('can-query-logic@1.1.6#src/serializers/basic-query', [ + 'require', + 'exports', + 'module', + 'can-symbol', + 'can-reflect', + '../types/basic-query', + '../set', + '../serializers/comparisons', + '../serializer', + '../types/comparisons', + '../types/make-maybe', + '../types/make-enum', + 'can-log/dev/dev', + '../helpers' +], function (require, exports, module) { + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + var BasicQuery = require('../types/basic-query'); + var set = require('../set'); + var comparisonsConverter = require('../serializers/comparisons'); + var Serializer = require('../serializer'); + var is = require('../types/comparisons'); + var makeMaybe = require('../types/make-maybe'); + var makeEnum = require('../types/make-enum'); + var logDev = require('can-log/dev/dev'); + var helpers = require('../helpers'); + var setTypeSymbol = canSymbol.for('can.SetType'); + var schemaSymbol = canSymbol.for('can.getSchema'); + var defaultQuery = new BasicQuery({}); + function getSchemaProperties(value) { + var constructor = value.constructor; + if (constructor && constructor[schemaSymbol]) { + var schema = constructor[schemaSymbol](); + return schema.keys || {}; + } else { + return {}; + } + } + function hydrateFilter(values, schemaProperties, hydrateUnknown) { + if (values && typeof values === 'object' && '$or' in values) { + return hydrateOrs(values.$or, schemaProperties, hydrateUnknown); + } else { + return hydrateAndValues(values, schemaProperties, hydrateUnknown); + } + } + var setTypeMap = new WeakMap(); + function hydrateAndValue(value, prop, SchemaType, hydrateChild) { + if (SchemaType) { + var SetType = SchemaType[setTypeSymbol]; + if (SetType) { + if (SetType.hydrate) { + return SetType.hydrate(value, comparisonsConverter.hydrate); + } else if (set.hasComparisons(SetType)) { + return new SetType(value); + } else { + return comparisonsConverter.hydrate(value, function (value) { + return new SetType(value); + }); + } + } else { + if (makeEnum.canMakeEnumSetType(SchemaType)) { + if (!setTypeMap.has(SchemaType)) { + setTypeMap.set(SchemaType, makeEnum.makeEnumSetType(SchemaType)); + } + SetType = setTypeMap.get(SchemaType); + return new SetType(value); + } else if (makeMaybe.canMakeMaybeSetType(SchemaType)) { + if (!setTypeMap.has(SchemaType)) { + setTypeMap.set(SchemaType, makeMaybe.makeMaybeSetTypes(SchemaType)); + } + SetType = setTypeMap.get(SchemaType).Maybe; + return SetType.hydrate(value, comparisonsConverter.hydrate); + } else { + return comparisonsConverter.hydrate(value, hydrateChild); + } + } + } else { + return comparisonsConverter.hydrate(value, hydrateChild); + } + } + function hydrateAndValues(values, schemaProperties, hydrateUnknown) { + schemaProperties = schemaProperties || {}; + function hydrateChild(value) { + if (value) { + if (Array.isArray(value)) { + return value.map(hydrateUnknown); + } else if (canReflect.isPlainObject(value)) { + return hydrateAndValues(value, getSchemaProperties(value)); + } + } + if (hydrateUnknown) { + return hydrateUnknown(value); + } else { + return value; + } + } + var clone = {}; + canReflect.eachKey(values, function (value, prop) { + clone[prop] = hydrateAndValue(value, prop, schemaProperties[prop], hydrateChild); + }); + return new BasicQuery.KeysAnd(clone); + } + function combineAnds(ands) { + var firstKeys = Object.keys(ands[0].values); + var keys = {}; + var keysCompare = new is.In(firstKeys); + firstKeys.map(function (key) { + keys[key] = []; + }); + var sameKeys = ands.every(function (and) { + if (!set.isEqual(keysCompare, new is.In(Object.keys(and.values)))) { + return false; + } + canReflect.eachKey(and.values, function (value, key) { + keys[key].push(value); + }); + return true; + }); + if (!sameKeys) { + return; + } + var unequalKeys = []; + firstKeys.forEach(function (key) { + var isEqual = keys[key].reduce(function (newSet, lastSetOrFalse) { + if (lastSetOrFalse === false) { + return false; + } + if (lastSetOrFalse === undefined) { + return newSet; + } + var res = set.isEqual(newSet, lastSetOrFalse); + return res ? newSet : false; + }); + if (!isEqual) { + unequalKeys.push(key); + } + }); + if (unequalKeys.length !== 1) { + return; + } + var unionKey = unequalKeys[0]; + var unioned = keys[unionKey].reduce(function (cur, last) { + return set.union(cur, last); + }, set.EMPTY); + var result = {}; + firstKeys.map(function (key) { + result[key] = keys[key][0]; + }); + result[unionKey] = unioned; + return new BasicQuery.KeysAnd(result); + } + function hydrateOrs(values, schemaProperties, hydrateUnknown) { + var comparisons = values.map(function (value) { + return hydrateAndValues(value, schemaProperties, hydrateUnknown); + }); + var combined = combineAnds(comparisons); + if (combined) { + return combined; + } + return new BasicQuery.Or(comparisons); + } + function recursivelyAddOrs(ors, value, serializer, key) { + value.orValues().forEach(function (orValue) { + if (typeof orValue.orValues === 'function') { + recursivelyAddOrs(ors, orValue, serializer, key); + } else { + var result = {}; + result[key] = serializer(orValue); + ors.push(result); + } + }); + } + module.exports = function (schema) { + var id = schema.identity && schema.identity[0]; + var keys = schema.keys; + var serializeMap = [ + [ + BasicQuery.Or, + function (or, serializer) { + return or.values.map(function (value) { + return serializer(value); + }); + } + ], + [ + BasicQuery.KeysAnd, + function (and, serializer) { + var ors = []; + var result = {}; + canReflect.eachKey(and.values, function (value, key) { + if (typeof value.orValues === 'function') { + recursivelyAddOrs(ors, value, serializer, key); + } else { + result[key] = serializer(value); + } + }); + if (ors.length) { + if (ors.length === 1) { + return ors[0]; + } else { + return { + $or: ors.map(function (orPart) { + return canReflect.assign(canReflect.serialize(result), orPart); + }) + }; + } + } else { + return result; + } + } + ], + [ + BasicQuery.RecordRange, + function (range) { + return { + start: range.start, + end: range.end + }; + } + ], + [ + BasicQuery, + function (basicQuery, childSerializer) { + var filter = set.isEqual(basicQuery.filter, set.UNIVERSAL) ? {} : childSerializer(basicQuery.filter); + var res = {}; + if (canReflect.size(filter) !== 0) { + res.filter = filter; + } + if (!set.isEqual(basicQuery.page, defaultQuery.page)) { + res.page = { start: basicQuery.page.start }; + if (basicQuery.page.end !== defaultQuery.page.end) { + res.page.end = basicQuery.page.end; + } + } + if (basicQuery.sort.key !== id) { + res.sort = basicQuery.sort.key; + } + return res; + } + ] + ]; + var Sort = BasicQuery.makeSort(keys, hydrateAndValue); + var serializer = new Serializer(serializeMap); + serializer.add(comparisonsConverter.serializer); + return { + hydrate: function (data) { + var filter = canReflect.serialize(data.filter); + var filterAnd = hydrateFilter(filter, keys, helpers.valueHydrator); + var query = { filter: filterAnd }; + if (data.page) { + query.page = new BasicQuery.RecordRange(data.page.start, data.page.end); + } + if (data.sort) { + query.sort = new Sort(data.sort); + } else { + query.sort = new Sort(id); + } + return new BasicQuery(query); + }, + serializer: serializer + }; + }; +}); +/*can-query-logic@1.1.6#src/serializers/basic-query-test*/ +define('can-query-logic@1.1.6#src/serializers/basic-query-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './basic-query', + 'can-reflect', + '../types/and-or-not', + '../types/comparisons', + '../types/make-maybe', + 'can-test-helpers' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var makeBasicQueryConvert = require('./basic-query'); + var canReflect = require('can-reflect'); + var logicTypes = require('../types/and-or-not'); + var is = require('../types/comparisons'); + var makeMaybe = require('../types/make-maybe'); + var testHelpers = require('can-test-helpers'); + QUnit.module('can-query-logic/serializers/basic-query'); + var EmptySchema = { + kind: 'record', + identity: ['id'], + keys: {} + }; + QUnit.test('basics', function () { + var query = { filter: { foo: 'bar' } }; + var converter = makeBasicQueryConvert(EmptySchema); + var basicQuery = converter.hydrate(query); + var returnedQuery = converter.serializer.serialize(basicQuery); + QUnit.deepEqual(returnedQuery, query, 'got back what we give'); + }); + QUnit.test('nested properties', function () { + var query = { filter: { name: { first: 'justin' } } }; + var converter = makeBasicQueryConvert(EmptySchema); + var basicQuery = converter.hydrate(query); + QUnit.deepEqual(basicQuery.filter, new logicTypes.KeysAnd({ name: new logicTypes.KeysAnd({ first: new is.In(['justin']) }) }), 'adds nested ands'); + }); + QUnit.test('$or with the same types unify into maybe', function () { + var MaybeSet = makeMaybe([null]); + var converter = makeBasicQueryConvert({ + identity: ['id'], + keys: { + age: canReflect.assignSymbols({}, { 'can.SetType': MaybeSet }), + foo: String + } + }); + var query = { + filter: { + $or: [ + { + foo: 'bar', + age: { $gt: 3 } + }, + { + foo: 'bar', + age: null + } + ] + } + }; + var basicQuery = converter.hydrate(query); + QUnit.deepEqual(basicQuery.filter, new logicTypes.KeysAnd({ + foo: new is.In(['bar']), + age: new MaybeSet({ + range: new is.GreaterThan(3), + enum: new is.In([null]) + }) + })); + var res = converter.serializer.serialize(basicQuery); + QUnit.deepEqual(res, { + filter: { + $or: [ + { + foo: 'bar', + age: { $gt: 3 } + }, + { + foo: 'bar', + age: null + } + ] + } + }, 'serialized'); + }); + QUnit.test('auto-convert or schema into maybe type', function () { + var MaybeNumber = canReflect.assignSymbols({}, { + 'can.new': function (val) { + if (val == null) { + return val; + } + return +val; + }, + 'can.getSchema': function () { + return { + type: 'Or', + values: [ + Number, + undefined, + null + ] + }; + } + }); + var converter = makeBasicQueryConvert({ + identity: ['id'], + keys: { + age: MaybeNumber, + foo: String + } + }); + var query = { + filter: { + $or: [ + { + foo: 'bar', + age: { $gt: '3' } + }, + { + foo: 'bar', + age: null + } + ] + } + }; + var basicQuery = converter.hydrate(query); + var res = converter.serializer.serialize(basicQuery); + QUnit.deepEqual(res, { + filter: { + $or: [ + { + foo: 'bar', + age: { $gt: 3 } + }, + { + foo: 'bar', + age: null + } + ] + } + }, 'serialized'); + }); + testHelpers.dev.devOnlyTest('warn if query properties are not defined (#8)', function () { + QUnit.expect(3); + var message = 'can-query-logic: Ignoring keys: start, end.'; + var finishErrorCheck = testHelpers.dev.willWarn(message, function (actualMessage, success) { + QUnit.equal(actualMessage, message, 'Warning is expected message'); + QUnit.ok(success); + }); + var query = { + filter: { name: { first: 'justin' } }, + start: 0, + end: 1 + }; + var converter = makeBasicQueryConvert(EmptySchema); + converter.hydrate(query); + QUnit.equal(finishErrorCheck(), 1); + }); + QUnit.test('gt and lt', function () { + var query = { + filter: { + age: { + $gt: 0, + $lt: 100 + } + } + }; + var converter = makeBasicQueryConvert(EmptySchema); + var basicQuery = converter.hydrate(query); + QUnit.deepEqual(basicQuery.filter, new logicTypes.KeysAnd({ + age: new is.And([ + new is.GreaterThan(0), + new is.LessThan(100) + ]) + })); + var res = converter.serializer.serialize(basicQuery); + QUnit.deepEqual(res, { + filter: { + age: { + $gt: 0, + $lt: 100 + } + } + }); + }); + QUnit.test('basicquery with no sort', function () { + var query = {}; + var converter = makeBasicQueryConvert({ + identity: ['id'], + type: 'map', + keys: { + id: function (val) { + return val; + } + } + }); + var basicQuery = converter.hydrate(query); + var objs = [ + { id: 0 }, + { id: 2 } + ]; + var item = { id: 1 }; + var res = basicQuery.index(item, objs); + QUnit.equal(res, 1, 'inserted at 1'); + }); +}); +/*can-query-logic@1.1.6#src/serializers/comparisons-test*/ +define('can-query-logic@1.1.6#src/serializers/comparisons-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './comparisons', + 'can-reflect' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var comparisons = require('./comparisons'); + var canReflect = require('can-reflect'); + QUnit.module('can-query-logic/serializers/comparisons'); + QUnit.test('hydrate and serialize', function () { + var Type = function (value) { + this.value = value; + }; + canReflect.assignSymbols(Type.prototype, { + 'can.serialize': function () { + return this.value; + } + }); + var hydrated = comparisons.hydrate({ + $in: [ + 1, + 2 + ] + }, function (value) { + return new Type(value); + }); + QUnit.deepEqual(hydrated.values, [ + new Type(1), + new Type(2) + ], 'hydrated'); + var serialized = comparisons.serializer.serialize(hydrated); + QUnit.deepEqual(serialized, { + $in: [ + 1, + 2 + ] + }, 'serialized'); + }); + QUnit.test('unknown hydrator is called in all cases', function () { + var hydrated = []; + var addToHydrated = function (value) { + hydrated.push(value); + }; + comparisons.hydrate({ + $in: [ + 1, + 2 + ] + }, addToHydrated); + comparisons.hydrate('abc', addToHydrated); + comparisons.hydrate([ + 'x', + 'y' + ], addToHydrated); + QUnit.deepEqual(hydrated, [ + 1, + 2, + 'abc', + 'x', + 'y' + ], 'hydrated called with the right stuff'); + }); +}); +/*can-query-logic@1.1.6#src/types/make-maybe-test*/ +define('can-query-logic@1.1.6#src/types/make-maybe-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './make-maybe', + './comparisons', + '../set', + 'can-reflect' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var makeMaybe = require('./make-maybe'); + var is = require('./comparisons'); + var set = require('../set'); + var canReflect = require('can-reflect'); + QUnit.module('can-query-logic/types/make-maybe'); + function DateStringSet(value) { + this.value = value; + } + DateStringSet.prototype.valueOf = function () { + return this.value == null ? this.value : new Date(this.value).getTime(); + }; + var ComparisonSet = function (value) { + this.value = value; + }; + ComparisonSet.prototype.valueOf = function () { + return this.value; + }; + var MaybeDateStringSet = makeMaybe([ + null, + undefined + ], DateStringSet); + QUnit.test('construtor normalizes', function () { + var isNull_3 = new MaybeDateStringSet({ + range: new is.In([ + null, + 3 + ]) + }); + QUnit.deepEqual(isNull_3.range, new is.In([3]), '3 left in range'); + QUnit.deepEqual(isNull_3.enum, new is.In([null]), 'range moved to in'); + var isNull_3AsDateString = new MaybeDateStringSet({ + range: new is.In([ + new DateStringSet(null), + new DateStringSet(3) + ]) + }); + QUnit.deepEqual(isNull_3AsDateString.range, new is.In([new DateStringSet(3)]), '3 left in range'); + QUnit.deepEqual(isNull_3AsDateString.enum, new is.In([new DateStringSet(null)]), 'range moved to in'); + var isNull = new MaybeDateStringSet({ range: new is.In([null]) }); + QUnit.deepEqual(isNull.range, set.EMPTY, 'empty if only null'); + QUnit.deepEqual(isNull.enum, new is.In([null]), 'range moved to in'); + var res = new MaybeDateStringSet({ + range: new is.NotIn([ + null, + 3 + ]) + }); + QUnit.deepEqual(res.range, new is.NotIn([3]), 'not in range'); + QUnit.deepEqual(res.enum, new is.In([undefined]), 'not in enum'); + res = new MaybeDateStringSet({ + range: new is.And([ + new is.NotIn([null]), + new is.GreaterThan(4) + ]) + }); + QUnit.deepEqual(res.range, new is.GreaterThan(4), 'And with not in'); + QUnit.deepEqual(res.enum, set.EMPTY, 'And with not in'); + }); + QUnit.test('difference with universal', function () { + var res; + var gt3 = new MaybeDateStringSet({ range: new is.GreaterThan(3) }); + res = set.difference(set.UNIVERSAL, gt3); + QUnit.deepEqual(res, new MaybeDateStringSet({ + enum: new is.In([ + null, + undefined + ]), + range: new is.LessThanEqual(3) + }), 'UNIVERSAL \\ $gt:3'); + res = set.difference(set.UNIVERSAL, new MaybeDateStringSet({ range: new is.In([null]) })); + QUnit.deepEqual(res, new MaybeDateStringSet({ + range: set.UNIVERSAL, + enum: new is.In([undefined]) + }), 'UNIVERSAL \\ null'); + res = set.difference(set.UNIVERSAL, new MaybeDateStringSet({ range: new is.NotIn([null]) })); + QUnit.deepEqual(res, new MaybeDateStringSet({ + range: set.UNIVERSAL, + enum: new is.In([null]) + }), 'UNIVERSAL \\ !null'); + res = set.difference(set.UNIVERSAL, new MaybeDateStringSet({ + enum: new is.In([ + null, + undefined + ]), + range: new is.LessThanEqual(3) + })); + QUnit.deepEqual(res, gt3, 'secondary and primary'); + }); + QUnit.test('difference', function () { + var res; + var gt3 = new MaybeDateStringSet({ range: new is.GreaterThan(3) }); + res = set.difference(new MaybeDateStringSet({ range: new is.GreaterThan(3) }), new MaybeDateStringSet({ range: new is.GreaterThan(4) })); + QUnit.deepEqual(res, new MaybeDateStringSet({ range: set.difference(new is.GreaterThan(3), new is.GreaterThan(4)) }), '$gt:3 \\ $gt:4'); + res = set.difference(new MaybeDateStringSet({ range: new is.NotIn([undefined]) }), new MaybeDateStringSet({ + range: new is.LessThanEqual(3), + enum: new is.In([null]) + })); + QUnit.deepEqual(res, new MaybeDateStringSet({ range: new is.GreaterThan(3) }), '{ne: undef} \\ {lt: 3} | null -> {gte: 3}'); + res = set.difference(new MaybeDateStringSet({ range: new is.NotIn([undefined]) }), new MaybeDateStringSet({ range: new is.LessThanEqual(3) })); + QUnit.deepEqual(res, new MaybeDateStringSet({ + range: new is.GreaterThan(3), + enum: new is.In([null]) + }), '{ne: undef} \\ {lt: 3}|null -> {gte: 3} | null'); + res = set.difference(set.UNIVERSAL, new MaybeDateStringSet({ range: new is.In([null]) })); + QUnit.deepEqual(res, new MaybeDateStringSet({ range: new is.NotIn([null]) }), 'UNIVERSAL \\ null'); + res = set.difference(set.UNIVERSAL, new MaybeDateStringSet({ + enum: new is.In([ + null, + undefined + ]), + range: new is.LessThanEqual(3) + })); + QUnit.deepEqual(res, gt3, 'secondary and primary'); + res = set.difference(new MaybeDateStringSet({ + range: new is.In([3]), + enum: set.EMPTY + }), new MaybeDateStringSet({ + range: new is.In([3]), + enum: set.EMPTY + })); + QUnit.equal(res, set.EMPTY, 'equal is empty'); + }); + QUnit.test('difference with ComparisonSet', function () { + var three = new ComparisonSet(3), four = new ComparisonSet(3); + var res; + var gt3 = new MaybeDateStringSet({ range: new is.GreaterThan(three) }); + res = set.difference(new MaybeDateStringSet({ range: new is.GreaterThan(three) }), new MaybeDateStringSet({ range: new is.GreaterThan(four) })); + QUnit.deepEqual(res, new MaybeDateStringSet({ range: set.difference(new is.GreaterThan(three), new is.GreaterThan(four)) }), '$gt:3 \\ $gt:4'); + res = set.difference(new MaybeDateStringSet({ range: new is.NotIn([undefined]) }), new MaybeDateStringSet({ + range: new is.LessThanEqual(three), + enum: new is.In([null]) + })); + QUnit.deepEqual(res, new MaybeDateStringSet({ range: new is.GreaterThan(three) }), '{ne: undef} \\ {lt: 3} | null -> {gte: 3}'); + res = set.difference(new MaybeDateStringSet({ range: new is.NotIn([undefined]) }), new MaybeDateStringSet({ range: new is.LessThanEqual(three) })); + QUnit.deepEqual(res, new MaybeDateStringSet({ + range: new is.GreaterThan(three), + enum: new is.In([null]) + }), '{ne: undef} \\ {lt: 3}|null -> {gte: 3} | null'); + res = set.difference(set.UNIVERSAL, new MaybeDateStringSet({ range: new is.In([null]) })); + QUnit.deepEqual(res, new MaybeDateStringSet({ range: new is.NotIn([null]) }), 'UNIVERSAL \\ null'); + res = set.difference(set.UNIVERSAL, new MaybeDateStringSet({ + enum: new is.In([ + null, + undefined + ]), + range: new is.LessThanEqual(three) + })); + QUnit.deepEqual(res, gt3, 'secondary and primary'); + }); + QUnit.test('intersection', function () { + var res; + res = set.intersection(new MaybeDateStringSet({ + range: new is.GreaterThan(3), + enum: new is.In([null]) + }), new MaybeDateStringSet({ + range: new is.GreaterThan(5), + enum: new is.In([ + null, + undefined + ]) + })); + QUnit.deepEqual(res, new MaybeDateStringSet({ + range: new is.GreaterThan(5), + enum: new is.In([null]) + }), 'got the right thing'); + }); + QUnit.test('union', function () { + var res; + res = set.union(new MaybeDateStringSet({ + range: new is.GreaterThan(3), + enum: new is.In([null]) + }), new MaybeDateStringSet({ + range: new is.GreaterThan(5), + enum: new is.In([undefined]) + })); + QUnit.deepEqual(res, new MaybeDateStringSet({ + range: new is.GreaterThan(3), + enum: new is.In([ + null, + undefined + ]) + }), 'got the right thing'); + }); + QUnit.test('isSubset', function () { + var res; + res = set.isSubset(new MaybeDateStringSet({ + range: new is.In([3]), + enum: set.EMPTY + }), new MaybeDateStringSet({ + range: new is.In([3]), + enum: set.EMPTY + })); + QUnit.ok(res, 'is a subset'); + }); + QUnit.test('can make maybe type from normal type and makeMaybeSetType', function () { + var MaybeNumber = canReflect.assignSymbols({}, { + 'can.new': function (val) { + if (val == null) { + return val; + } + return +val; + }, + 'can.getSchema': function () { + return { + type: 'Or', + values: [ + Number, + undefined, + null + ] + }; + } + }); + QUnit.ok(makeMaybe.canMakeMaybeSetType(MaybeNumber), 'got everything we need'); + var types = makeMaybe.makeMaybeSetTypes(MaybeNumber); + var notUndefined = new types.Maybe({ range: new is.NotIn([new types.ComparisonSetType(undefined)]) }), nullOrLTE3 = new types.Maybe({ + range: new is.LessThanEqual(new types.ComparisonSetType(3)), + enum: new is.In([new types.ComparisonSetType(null)]) + }); + var res = set.difference(notUndefined, nullOrLTE3); + QUnit.deepEqual(res, new types.Maybe({ range: new is.GreaterThan(new types.ComparisonSetType(3)) }), '{ne: undef} \\ {lt: 3} | null -> {gte: 3}'); + }); + QUnit.test('can make a maybe type from a ComparisonSetType', function () { + function toDate(str) { + var type = typeof str; + if (type === 'string') { + str = Date.parse(str); + return isNaN(str) ? null : new Date(str); + } else if (type === 'number') { + return new Date(str); + } else { + return str; + } + } + function DateStringSet(dateStr) { + this.setValue = dateStr; + var date = toDate(dateStr); + this.value = date == null ? date : date.getTime(); + } + DateStringSet.prototype.valueOf = function () { + return this.value; + }; + canReflect.assignSymbols(DateStringSet.prototype, { + 'can.serialize': function () { + return this.setValue; + } + }); + var MaybeDate = canReflect.assignSymbols({}, { + 'can.new': toDate, + 'can.getSchema': function () { + return { + type: 'Or', + values: [ + Date, + undefined, + null + ] + }; + }, + 'can.ComparisonSetType': DateStringSet + }); + QUnit.ok(makeMaybe.canMakeMaybeSetType(MaybeDate), 'got everything we need'); + var types = makeMaybe.makeMaybeSetTypes(MaybeDate); + QUnit.equal(types.ComparisonSetType, DateStringSet, 'got the comparison type'); + var date1982_10_20 = new Date(1982, 9, 20).toString(); + var notUndefined = new types.Maybe({ range: new is.NotIn([new types.ComparisonSetType(undefined)]) }), nullOrLTE3 = new types.Maybe({ + range: new is.LessThanEqual(new types.ComparisonSetType(date1982_10_20)), + enum: new is.In([new types.ComparisonSetType(null)]) + }); + var res = set.difference(notUndefined, nullOrLTE3); + QUnit.deepEqual(res, new types.Maybe({ range: new is.GreaterThan(new types.ComparisonSetType(date1982_10_20)) }), '{ne: undef} \\ {lt: \'' + date1982_10_20 + '\'} | null -> {gte: \'' + date1982_10_20 + '\'}'); + }); + QUnit.test('orValues', function () { + var res = new MaybeDateStringSet({ + range: new is.In([3]), + enum: set.EMPTY + }); + QUnit.deepEqual(res.orValues(), [new is.In([3])], 'only got range'); + res = new MaybeDateStringSet({ + range: set.EMPTY, + enum: new is.In([null]) + }); + QUnit.deepEqual(res.orValues(), [new is.In([null])], 'only got enum'); + }); +}); +/*can-query-logic@1.1.6#src/types/make-enum-test*/ +define('can-query-logic@1.1.6#src/types/make-enum-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './make-enum', + '../set', + 'can-reflect', + 'can-symbol' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var makeEnum = require('./make-enum'); + var set = require('../set'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + QUnit.module('can-query-logic/types/make-enum'); + QUnit.test('.isMember', function () { + var Status = makeEnum(function () { + }, [ + 'assigned', + 'complete' + ]); + var status = new Status(['assigned']); + QUnit.ok(status[canSymbol.for('can.isMember')]('assigned'), 'assigned is member'); + }); +}); +/*can-query-logic@1.1.6#can-query-logic*/ +define('can-query-logic@1.1.6#can-query-logic', [ + 'require', + 'exports', + 'module', + './src/set', + 'can-symbol', + 'can-reflect', + './src/serializers/basic-query', + './src/types/basic-query', + './src/types/comparisons', + './src/types/make-enum' +], function (require, exports, module) { + var set = require('./src/set'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + var makeBasicQueryConvert = require('./src/serializers/basic-query'); + var BasicQuery = require('./src/types/basic-query'); + var valueComparisons = require('./src/types/comparisons'); + var schemaSymbol = canSymbol.for('can.getSchema'); + var newSymbol = canSymbol.for('can.new'); + var makeEnum = require('./src/types/make-enum'); + function QueryLogic(Type, options) { + Type = Type || {}; + var passedHydrator = options && options.toQuery; + var passedSerializer = options && options.toParams; + var schema; + if (Type[schemaSymbol]) { + schema = Type[schemaSymbol](); + } else { + schema = Type; + } + var id = schema.identity && schema.identity[0]; + if (!id) { + schema.identity = ['id']; + } + var converter = makeBasicQueryConvert(schema), hydrate, serialize; + if (passedHydrator) { + hydrate = function (query) { + return converter.hydrate(passedHydrator(query)); + }; + } else { + hydrate = converter.hydrate; + } + if (passedSerializer) { + serialize = function (query) { + return passedSerializer(converter.serializer.serialize(query)); + }; + } else { + serialize = converter.serializer.serialize; + } + this.hydrate = hydrate; + this.serialize = serialize; + this.schema = schema; + } + function makeNewSet(prop) { + return function (qA, qB) { + var queryA = this.hydrate(qA), queryB = this.hydrate(qB); + var unionQuery = set[prop](queryA, queryB); + return this.serialize(unionQuery); + }; + } + function makeReturnValue(prop) { + return function (qA, qB) { + var queryA = this.hydrate(qA), queryB = this.hydrate(qB); + return set[prop](queryA, queryB); + }; + } + canReflect.assignSymbols(QueryLogic.prototype, { + 'can.getSchema': function () { + return this.schema; + } + }); + canReflect.assign(QueryLogic.prototype, { + union: makeNewSet('union'), + difference: makeNewSet('difference'), + intersection: makeNewSet('intersection'), + isEqual: makeReturnValue('isEqual'), + isProperSubset: makeReturnValue('isProperSubset'), + isSubset: makeReturnValue('isSubset'), + isSpecial: set.isSpecial, + isDefinedAndHasMembers: set.isDefinedAndHasMembers, + count: function (a) { + var queryA = this.hydrate(a); + return queryA.page.end - queryA.page.start + 1; + }, + identityKeys: function () { + return this.schema.identity; + }, + filterMembers: function (a, b, bData) { + var queryA = this.hydrate(a); + if (arguments.length >= 3) { + var queryB = this.hydrate(b); + return queryA.filterFrom(bData, queryB); + } else { + return queryA.filterFrom(b); + } + }, + filterMembersAndGetCount: function (a, b, bData) { + var queryA = this.hydrate(a), queryB = this.hydrate(b); + return queryA.filterMembersAndGetCount(bData, queryB); + }, + unionMembers: function (a, b, aData, bData) { + var queryA = this.hydrate(a), queryB = this.hydrate(b); + var schema = this.schema; + return queryA.merge(queryB, aData, bData, function (obj) { + return canReflect.getIdentity(obj, schema); + }); + }, + isMember: function (query, props) { + return this.hydrate(query).isMember(props); + }, + memberIdentity: function (props) { + return canReflect.getIdentity(props, this.schema); + }, + index: function (query, items, props) { + return this.hydrate(query).index(props, items); + }, + insert: function (query, items, item) { + var index = this.index(query, items, item); + if (index === undefined) { + index = items.length; + } + var copy = items.slice(0); + copy.splice(index, 0, item); + return copy; + }, + isPaginated: function (query) { + var basicQuery = this.hydrate(query); + return !set.isEqual(basicQuery.page, set.UNIVERSAL); + }, + removePagination: function (query) { + var basicQuery = this.hydrate(query); + basicQuery.removePagination(); + return this.serialize(basicQuery); + } + }); + for (var prop in set) { + if (QueryLogic[prop] === undefined) { + QueryLogic[prop] = set[prop]; + } + } + QueryLogic.makeEnum = function (values) { + var Type = function () { + }; + Type[newSymbol] = function (val) { + return val; + }; + makeEnum(Type, values); + return Type; + }; + QueryLogic.KeysAnd = BasicQuery.KeysAnd; + QueryLogic.ValuesOr = BasicQuery.Or; + QueryLogic.In = valueComparisons.In; + QueryLogic.NotIn = valueComparisons.NotIn; + QueryLogic.GreaterThan = valueComparisons.GreaterThan; + QueryLogic.GreaterThanEqual = valueComparisons.GreaterThanEqual; + QueryLogic.LessThan = valueComparisons.LessThan; + QueryLogic.LessThanEqual = valueComparisons.LessThanEqual; + QueryLogic.ValueAnd = valueComparisons.And; + QueryLogic.ValueOr = valueComparisons.Or; + module.exports = QueryLogic; +}); +/*can-query-logic@1.1.6#compat/compat*/ +define('can-query-logic@1.1.6#compat/compat', [ + 'require', + 'exports', + 'module', + '../can-query-logic', + 'can-reflect', + 'can-key/transform/transform', + 'can-key/delete/delete', + 'can-key/get/get', + '../src/types/make-enum', + '../src/set', + '../src/helpers' +], function (require, exports, module) { + var Query = require('../can-query-logic'); + var canReflect = require('can-reflect'); + var transform = require('can-key/transform/transform'); + var deleteKey = require('can-key/delete/delete'); + var getKey = require('can-key/get/get'); + var makeEnum = require('../src/types/make-enum'); + var SET = require('../src/set'); + var helpers = require('../src/helpers'); + var IsBoolean = function () { + }; + makeEnum(IsBoolean, [ + true, + false + ], function (value) { + if (value === 'true') { + return true; + } else if (value === 'false') { + return false; + } else { + return value; + } + }); + function hasKey(obj, keys, parent, parentKey) { + if (obj && typeof obj === 'object') { + for (var key in obj) { + if (keys[key]) { + if (typeof keys[key] === 'function') { + parent[parentKey] = keys[key](obj); + } else { + return true; + } + } else { + if (hasKey(obj[key], keys, obj, key)) { + return true; + } + } + } + } + return false; + } + function convertToJSONAPISort(sortPropValue) { + var parts = sortPropValue.split(' '); + var isDesc = (parts[1] || '').toLowerCase() === 'desc'; + return isDesc ? '-' + parts[0] : parts[0]; + } + function convertToLegacySort(value) { + var result = helpers.sortData(value); + return result.desc ? '-' + result.prop : result.prop; + } + var defaultAlgebra; + var set = { + UNIVERSAL: SET.UNIVERSAL, + EMPTY: SET.EMPTY, + UNDEFINABLE: SET.UNDEFINABLE, + UNKNOWABLE: SET.UNKNOWABLE, + Algebra: function () { + var mutators = { + schema: [], + hydrate: [], + serialize: [] + }; + canReflect.eachIndex(arguments, function (value) { + for (var prop in value) { + if (mutators[prop]) { + mutators[prop].push(value[prop]); + } else { + throw new Error('can-query-logic: This type of configuration is not supported. Please use can-query-logic directly.'); + } + } + }); + var obj = canReflect.assignSymbols({}, { + 'can.getSchema': function () { + var schema = { + kind: 'record', + identity: [], + keys: {} + }; + mutators.schema.forEach(function (updateSchema) { + updateSchema(schema); + }); + if (!schema.identity.length) { + schema.identity.push('id'); + } + return schema; + } + }); + return new Query(obj, { + toQuery: function (data) { + return mutators.hydrate.reduce(function (last, hydrator) { + return hydrator(last); + }, { filter: data }); + }, + toParams: function (data) { + if (SET.isSpecial(data)) { + return data; + } + if (Array.isArray(data.filter)) { + return SET.UNDEFINABLE; + } + var filter = data.filter || {}; + if (hasKey(filter, { + '$ne': true, + '$in': function (val) { + return val['$in']; + } + })) { + return SET.UNDEFINABLE; + } + var out = mutators.serialize.reduce(function (last, serializer) { + return serializer(last); + }, data); + filter = out.filter || {}; + delete out.filter; + return canReflect.assign(out, filter); + } + }); + }, + Translate: function (clause, prop) { + if (clause !== 'where') { + throw new Error('can-query-logic/compat.Translate is only able to translate the where clause'); + } + return { + hydrate: function (raw) { + var clone = canReflect.serialize(raw); + var value = clone.filter[prop]; + delete clone.filter[prop]; + if (value) { + canReflect.assign(clone.filter, value); + } + return clone; + }, + serialize: function (query) { + if (query.filter) { + var clone = canReflect.serialize(query); + var filter = query.filter; + clone.filter = {}; + clone.filter[prop] = filter; + return clone; + } else { + return query; + } + } + }; + }, + props: { + boolean: function (prop) { + return { + schema: function (schema) { + schema.keys[prop] = IsBoolean; + } + }; + }, + dotNotation: function () { + return {}; + }, + enum: function (property, propertyValues) { + function Enum() { + } + makeEnum(Enum, propertyValues); + return { + schema: function (schema) { + schema.keys[property] = Enum; + } + }; + }, + id: function (id) { + return { + 'schema': function (schema) { + schema.identity.push(id); + } + }; + }, + offsetLimit: function (offset, limit) { + offset = offset || 'offset'; + limit = limit || 'limit'; + return { + hydrate: function (raw) { + var clone = canReflect.serialize(raw); + if (offset in clone.filter || limit in clone.filter) { + clone.page = {}; + } + if (offset in clone.filter) { + clone.page.start = parseInt(clone.filter[offset], 10); + delete clone.filter[offset]; + } + if (limit in clone.filter) { + clone.page.end = (clone.page.start || 0) + parseInt(clone.filter[limit], 10) - 1; + delete clone.filter[limit]; + } + return clone; + }, + serialize: function (raw) { + var clone = canReflect.serialize(raw); + if (clone.page) { + clone[offset] = clone.page.start; + clone[limit] = clone.page.end - clone.page.start + 1; + delete clone.page; + } + return clone; + } + }; + }, + rangeInclusive: function (start, end) { + var hydrateTransfomer = {}; + hydrateTransfomer['filter.' + start] = 'page.start'; + hydrateTransfomer['filter.' + end] = 'page.end'; + var serializeTransformer = { + 'page.start': start, + 'page.end': end + }; + return { + hydrate: function (raw) { + var res = transform(raw, hydrateTransfomer); + if (res.page) { + if (res.page.start) { + res.page.start = parseInt(res.page.start, 10); + } + if (res.page.end) { + res.page.end = parseInt(res.page.end, 10); + } + } + return res; + }, + serialize: function (raw) { + return transform(raw, serializeTransformer); + } + }; + }, + ignore: function (prop) { + return { + hydrate: function (raw) { + var clone = canReflect.serialize(raw); + delete clone.filter[prop]; + return clone; + } + }; + }, + sort: function (prop, sortFunc) { + if (!prop) { + prop = 'sort'; + } + if (sortFunc) { + throw new Error('can-query-logic/compat.sort - sortFunc is not supported'); + } + return { + hydrate: function (raw) { + var clone = canReflect.serialize(raw); + var sort = getKey(clone, 'filter.' + prop); + if (sort !== undefined) { + deleteKey(clone, 'filter.' + prop); + clone.sort = convertToJSONAPISort(sort); + } + return clone; + }, + serialize: function (raw) { + var clone = canReflect.serialize(raw); + var sort = clone.sort; + if (sort !== undefined) { + delete clone.sort; + clone[prop] = convertToLegacySort(sort); + } + return clone; + } + }; + } + } + }; + function makeAlgebra(algebra) { + if (!algebra) { + return defaultAlgebra; + } else if (!(algebra instanceof Query)) { + return new set.Algebra(algebra); + } + return algebra; + } + function makeFromTwoQueries(prop) { + set[prop] = function (a, b, algebra) { + return makeAlgebra(algebra)[prop](a, b); + }; + } + makeFromTwoQueries('difference'); + makeFromTwoQueries('union'); + makeFromTwoQueries('intersection'); + makeFromTwoQueries('isSubset'); + makeFromTwoQueries('isEqual'); + makeFromTwoQueries('isProperSubset'); + set.count = function (query, algebra) { + return makeAlgebra(algebra).count(query); + }; + set.comparators = set.props; + defaultAlgebra = new set.Algebra(); + module.exports = set; +}); +/*can-query-logic@1.1.6#compat/prop_tests/boolean_test*/ +define('can-query-logic@1.1.6#compat/prop_tests/boolean_test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + '../compat' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var set = require('../compat'), props = set.props; + QUnit.module('can-set compat props.boolean'); + test('boolean set.difference', function () { + var prop = props.boolean('completed'); + var res = set.difference({}, { completed: true }, prop); + deepEqual(res, { completed: false }, 'inverse of true'); + res = set.difference({}, { completed: false }, prop); + deepEqual(res, { completed: true }, 'inverse of false'); + }); + test('boolean set.union', function () { + var prop = props.boolean('completed'); + var res = set.union({ completed: false }, { completed: true }, prop); + deepEqual(res, {}, 'union of true and false is entire boolean set'); + }); + test('boolean set.intersection', function () { + var prop = props.boolean('completed'); + var res = set.intersection({ foo: 'bar' }, { completed: true }, prop); + deepEqual(res, { + foo: 'bar', + completed: true + }, 'intersection is false (#4)'); + }); + test('strings false and true are treated as booleans', function () { + var prop = props.boolean('completed'); + var res; + res = set.isSubset({}, { completed: 'true' }, prop); + ok(!res, '{} and \'true\' not a subset'); + res = set.isSubset({}, { completed: 'false' }, prop); + ok(!res, '{} and \'false\' not a subset'); + res = set.isSubset({ completed: 'true' }, {}, prop); + ok(res, 'subset'); + res = set.isSubset({ completed: 'false' }, {}, prop); + ok(res, 'subset'); + res = set.union({ completed: 'false' }, { completed: 'true' }, prop); + deepEqual(res, {}, 'union of true and false is entire boolean set'); + res = set.isEqual({ completed: false }, { completed: 'false' }, prop); + ok(res, 'false and \'false\''); + }); +}); +/*can-query-logic@1.1.6#compat/prop_tests/enum_test*/ +define('can-query-logic@1.1.6#compat/prop_tests/enum_test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + '../compat' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var set = require('../compat'), props = set.props; + QUnit.module('can-set compat props.enum'); + test('enum set.intersection', function () { + var prop = props['enum']('type', [ + 'new', + 'prep', + 'deliver', + 'delivered' + ]); + var res = set.intersection({}, { type: 'new' }, prop); + deepEqual(res, { type: 'new' }, 'single enum intersected with universal set is idempotent'); + res = set.intersection({}, { + type: [ + 'new', + 'prep' + ] + }, prop); + deepEqual(res, { + type: [ + 'new', + 'prep' + ] + }, 'array enum intersected with unversal set is idempotent'); + res = set.intersection({ type: ['prep'] }, { + type: [ + 'new', + 'prep' + ] + }, prop); + deepEqual(res, { type: 'prep' }, 'items v items intersection'); + res = set.intersection({ type: [] }, { + type: [ + 'new', + 'prep' + ] + }, prop); + deepEqual(res, set.EMPTY, 'empty v array intersection'); + res = set.intersection({ type: 'new' }, {}, prop); + deepEqual(res, { type: 'new' }, 'single v all'); + }); + test('enum set.difference', function () { + var prop = props['enum']('type', [ + 'new', + 'prep', + 'deliver', + 'delivered' + ]), res; + res = set.difference({}, { type: 'new' }, prop); + deepEqual(res, { + type: [ + 'prep', + 'deliver', + 'delivered' + ] + }, 'difference from universal set'); + res = set.difference({}, { + type: [ + 'new', + 'prep' + ] + }, prop); + deepEqual(res, { + type: [ + 'deliver', + 'delivered' + ] + }, 'difference from universal set'); + res = set.difference({ type: ['prep'] }, { + type: [ + 'new', + 'prep' + ] + }, prop); + deepEqual(res, set.EMPTY, 'difference from a superset'); + res = set.difference({}, { + type: [ + 'new', + 'prep' + ] + }, prop); + deepEqual(res, { + type: [ + 'deliver', + 'delivered' + ] + }, 'empty enum definition is same as universal set'); + res = set.difference({ type: 'new' }, {}, prop); + deepEqual(res, set.EMPTY, 'all'); + }); + test('enum set.union', function () { + var prop = props['enum']('type', [ + 'new', + 'prep', + 'deliver', + 'delivered' + ]); + var res = set.union({}, { type: 'new' }, prop); + deepEqual(res, {}, 'all'); + res = set.union({}, { + type: [ + 'new', + 'prep' + ] + }, prop); + deepEqual(res, {}, 'intersection'); + res = set.union({ type: ['prep'] }, { + type: [ + 'new', + 'prep' + ] + }, prop); + deepEqual(res, { + type: [ + 'prep', + 'new' + ] + }, 'union of a superset is superset'); + res = set.union({}, { + type: [ + 'new', + 'prep' + ] + }, prop); + deepEqual(res, {}, 'intersection'); + res = set.union({ type: 'new' }, {}, prop); + deepEqual(res, {}, 'all'); + res = set.union({ + type: [ + 'deliver', + 'delivered' + ] + }, { + type: [ + 'new', + 'prep' + ] + }, prop); + deepEqual(res, {}, 'intersection'); + }); + test('enum set.equal', function () { + var prop = props['enum']('type', [ + 'new', + 'prep', + 'deliver', + 'delivered' + ]), res; + res = set.isEqual({}, { + type: [ + 'new', + 'prep', + 'deliver', + 'delivered' + ] + }, prop); + deepEqual(res, true, 'subset of all possible enums is the same as universal set'); + res = set.isEqual({ type: ['prep'] }, { type: ['prep'] }, prop); + deepEqual(res, true, 'identical sets with single array enum are equal'); + res = set.isEqual({ type: 'prep' }, { type: 'prep' }, prop); + deepEqual(res, true, 'identical sets with single property enum are equal'); + res = set.isEqual({ type: 'new' }, { type: 'prep' }, prop); + deepEqual(res, false, 'two sets with different enum properties are not equal'); + }); + test('enum set.isSubset', function () { + var prop = props['enum']('type', [ + 'new', + 'prep', + 'deliver', + 'delivered' + ]); + var res = set.isSubset({}, { type: 'new' }, prop); + deepEqual(res, false, 'universal set is not a subset'); + res = set.isSubset({ type: 'new' }, {}, prop); + deepEqual(res, true, 'any single enum is a subset of universal set'); + res = set.isSubset({}, { + type: [ + 'new', + 'prep', + 'deliver', + 'delivered' + ] + }, prop); + deepEqual(res, true, 'enum set matching definition of universal set is a subset of universal set'); + res = set.isSubset({ type: ['prep'] }, { type: ['prep'] }, prop); + deepEqual(res, true, 'any list of possible enums are subset of universal set'); + res = set.isSubset({ type: 'prep' }, { type: 'prep' }, prop); + deepEqual(res, true, 'intersection'); + res = set.isSubset({ type: 'new' }, { type: 'prep' }, prop); + deepEqual(res, false, 'all'); + res = set.isSubset({ type: 'prep' }, { + type: [ + 'new', + 'prep', + 'deliver', + 'delivered' + ] + }, prop); + deepEqual(res, true, 'intersection'); + }); +}); +/*can-query-logic@1.1.6#compat/prop_tests/id_test*/ +define('can-query-logic@1.1.6#compat/prop_tests/id_test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + '../compat' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var set = require('../compat'), props = set.props; + QUnit.module('can-set props.id'); + test('id set.difference', function () { + var idProps = props.id('color'); + var res; + res = set.difference({ color: 'red' }, { color: 'blue' }, idProps); + deepEqual(res, { color: 'red' }, 'id changes always false'); + res = set.difference({ color: 'red' }, {}, idProps); + deepEqual(res, set.EMPTY, 'id removal always false'); + res = set.difference({}, { color: 'blue' }, idProps); + deepEqual(res, set.UNDEFINABLE, 'id addition always true'); + }); + test('id set.difference with where', function () { + var algebra = new set.Algebra(props.id('color'), props.enum('type', [ + 'light', + 'dark' + ])); + var res; + res = set.difference({ + color: 'red', + type: [ + 'light', + 'dark' + ] + }, { + color: 'blue', + type: 'light' + }, algebra); + deepEqual(res, { + color: 'red', + type: [ + 'light', + 'dark' + ] + }, 'id changes always false'); + res = set.difference({ + color: 'red', + type: [ + 'light', + 'dark' + ] + }, { type: 'light' }, algebra); + deepEqual(res, { + color: 'red', + type: 'dark' + }, 'id removal always false'); + var a2 = new set.Algebra(props.enum('color', [ + 'red', + 'green' + ])); + res = set.difference({ + color: [ + 'red', + 'green' + ] + }, { + status: 'accepted', + color: 'red' + }, a2); + deepEqual(res, set.UNDEFINABLE, 'id addition always true'); + res = set.difference({ + type: [ + 'light', + 'dark' + ] + }, { type: 'light' }, algebra); + deepEqual(res, { type: 'dark' }, 'no id clause, fall back to where'); + res = set.difference({ + color: 'red', + type: [ + 'light', + 'dark' + ] + }, { + color: 'red', + type: 'light' + }, algebra); + deepEqual(res, { + color: 'red', + type: 'dark' + }, 'no id change, fall back to where'); + }); +}); +/*can-query-logic@1.1.6#compat/prop_tests/rangeInclusive_test*/ +define('can-query-logic@1.1.6#compat/prop_tests/rangeInclusive_test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + '../compat' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var set = require('../compat'), props = set.props; + QUnit.module('can-set props.rangeInclusive'); + test('rangeInclusive set.equal', function () { + ok(set.isEqual({ + start: 0, + end: 100 + }, { + start: 0, + end: 100 + }, props.rangeInclusive('start', 'end')), 'they are equal'); + ok(!set.isEqual({ + start: 0, + end: 100 + }, { + start: 0, + end: 101 + }, props.rangeInclusive('start', 'end')), 'they are not equal'); + ok(!set.isEqual({ + start: 0, + end: 100 + }, { + start: 1, + end: 100 + }, props.rangeInclusive('start', 'end')), 'they are not equal'); + }); + test('rangeInclusive set.isSubset', function () { + ok(set.isSubset({ + start: 0, + end: 100 + }, { + start: 0, + end: 100 + }, props.rangeInclusive('start', 'end')), 'self is a subset'); + ok(set.isSubset({ + start: 0, + end: 100 + }, { + start: 0, + end: 101 + }, props.rangeInclusive('start', 'end')), 'end extends past subset'); + ok(!set.isSubset({ + start: 0, + end: 101 + }, { + start: 0, + end: 100 + }, props.rangeInclusive('start', 'end')), 'non-subset extends past end'); + ok(set.isSubset({ + start: 1, + end: 100 + }, { + start: 0, + end: 100 + }, props.rangeInclusive('start', 'end')), 'start extends before subset'); + ok(!set.isSubset({ + start: 0, + end: 100 + }, { + start: 1, + end: 100 + }, props.rangeInclusive('start', 'end')), 'non-subset extends before start'); + }); + test('rangeInclusive set.difference', function () { + var prop = props.rangeInclusive('start', 'end'); + var res = set.difference({ + start: 0, + end: 99 + }, { + start: 50, + end: 101 + }, prop); + deepEqual(res, { + start: 0, + end: 49 + }, 'got a diff'); + res = set.difference({}, { + start: 0, + end: 10 + }, prop); + deepEqual(res, { start: 11 }, 'universal set'); + res = set.difference({ + start: 0, + end: 49 + }, { + start: 50, + end: 101 + }, prop); + deepEqual(res, { + start: 0, + end: 49 + }, 'side by side'); + res = set.difference({ + start: 0, + end: 49 + }, { + start: 0, + end: 20 + }, prop); + deepEqual(res, { + start: 21, + end: 49 + }, 'first set extends past second'); + res = set.difference({ + start: 0, + end: 49 + }, { + start: 20, + end: 49 + }, prop); + deepEqual(res, { + start: 0, + end: 19 + }, 'first set starts before second'); + }); + test('rangeInclusive set.union', function () { + var prop = props.rangeInclusive('start', 'end'); + var res = set.union({ + start: 0, + end: 99 + }, { + start: 50, + end: 101 + }, prop); + deepEqual(res, { + start: 0, + end: 101 + }, 'got a union'); + res = set.union({}, { + start: 0, + end: 10 + }, prop); + deepEqual(res, {}, 'universal set'); + res = set.union({ + start: 100, + end: 199 + }, { + start: 200, + end: 299 + }, prop); + deepEqual(res, { + start: 100, + end: 299 + }, 'no intersection'); + res = set.union({ + start: 200, + end: 299 + }, { + start: 100, + end: 199 + }, prop); + deepEqual(res, { + start: 100, + end: 299 + }, 'no intersection with either argument order'); + res = set.union({ + start: 200, + end: 299 + }, { + start: 100, + end: 209 + }, prop); + deepEqual(res, { + start: 100, + end: 299 + }, 'sets can intersect'); + res = set.union({ + start: 100, + end: 209 + }, { + start: 200, + end: 299 + }, prop); + deepEqual(res, { + start: 100, + end: 299 + }, 'sets can intersect with either argument order'); + res = set.union({ + start: 100, + end: 299 + }, { + start: 103, + end: 209 + }, prop); + deepEqual(res, { + start: 100, + end: 299 + }, 'first set contains second'); + res = set.union({ + start: 100, + end: 299 + }, { + start: 103, + end: 209 + }, prop); + deepEqual(res, { + start: 100, + end: 299 + }, 'second set contains first'); + res = set.union({ + start: 100, + end: 299 + }, { + start: 100, + end: 299 + }, prop); + deepEqual(res, { + start: 100, + end: 299 + }, 'union of identical sets is the same as those sets'); + }); + test('rangeInclusive set.count', function () { + var prop = props.rangeInclusive('start', 'end'); + var res = set.count({ + start: 0, + end: 99 + }, prop); + equal(res, 100, 'count is right'); + }); + test('rangeInclusive set.intersection', function () { + var prop = props.rangeInclusive('start', 'end'); + var res = set.intersection({ + start: 0, + end: 99 + }, { + start: 50, + end: 101 + }, prop); + deepEqual(res, { + start: 50, + end: 99 + }, 'got a intersection'); + res = set.intersection({ + start: 0, + end: 10, + age: 35 + }, { + start: 0, + end: 100, + name: 'JBM' + }, prop); + deepEqual(res, set.UNDEFINABLE, 'got a intersection'); + }); + test('rangeInclusive with string numbers (#17)', function () { + var algebra = new set.Algebra(props.rangeInclusive('start', 'end')); + ok(algebra.isSubset({ + start: '1', + end: '100' + }, { + start: '0', + end: '100' + }), '.subset'); + var res = algebra.filterMembers({ + start: '2', + end: '3' + }, { + start: '1', + end: '4' + }, [ + { id: 1 }, + { id: 2 }, + { id: 3 }, + { id: 4 } + ]); + deepEqual(res, [ + { id: 2 }, + { id: 3 } + ], '.filterMembers'); + res = algebra.unionMembers({ + start: '2', + end: '3' + }, { + start: '1', + end: '4' + }, [ + { id: 2 }, + { id: 3 } + ], [ + { id: 1 }, + { id: 2 }, + { id: 3 }, + { id: 4 } + ]); + deepEqual(res, [ + { id: 1 }, + { id: 2 }, + { id: 3 }, + { id: 4 } + ], '.unionMembers'); + }); +}); +/*can-query-logic@1.1.6#compat/prop_tests/offsetLimit_test*/ +define('can-query-logic@1.1.6#compat/prop_tests/offsetLimit_test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + '../compat' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var set = require('../compat'), props = set.props; + QUnit.module('can-set props.limitOffset'); + test('offsetLimit set.equal', function () { + ok(set.isEqual({ + offset: 0, + limit: 99 + }, { + offset: 0, + limit: 99 + }, props.offsetLimit('offset', 'limit')), 'they are equal'); + ok(!set.isEqual({ + offset: 0, + limit: 100 + }, { + offset: 0, + limit: 101 + }, props.offsetLimit('offset', 'limit')), 'they are not equal'); + ok(!set.isEqual({ + offset: 0, + limit: 100 + }, { + offset: 1, + limit: 100 + }, props.offsetLimit('offset', 'limit')), 'they are not equal'); + }); + test('offsetLimit set.union', function () { + var prop = props.offsetLimit('offset', 'limit'), res; + res = set.union({ + offset: 0, + limit: 100 + }, { + offset: 50, + limit: 52 + }, prop); + deepEqual(res, { + offset: 0, + limit: 102 + }, 'got a union'); + res = set.union({}, { + offset: 0, + limit: 10 + }, prop); + deepEqual(res, {}, 'universal set'); + res = set.union({ + offset: 100, + limit: 100 + }, { + offset: 200, + limit: 100 + }, prop); + deepEqual(res, { + offset: 100, + limit: 200 + }, 'no intersection'); + res = set.union({ + offset: 200, + limit: 100 + }, { + offset: 100, + limit: 100 + }, prop); + deepEqual(res, { + offset: 100, + limit: 200 + }, 'no intersection with either argument order'); + res = set.union({ + offset: 100, + limit: 110 + }, { + offset: 200, + limit: 100 + }, prop); + deepEqual(res, { + offset: 100, + limit: 200 + }, 'sets can intersect with either argument order'); + }); + test('rangeInclusive set.count', function () { + var prop = props.offsetLimit('offset', 'limit'); + var res = set.count({ + offset: 0, + limit: 100 + }, prop); + equal(res, 100, 'count is right'); + }); + test('rangeInclusive set.intersection', function () { + var prop = props.offsetLimit('offset', 'limit'); + var res = set.intersection({ + offset: 0, + limit: 100 + }, { + offset: 50, + limit: 52 + }, prop); + deepEqual(res, { + offset: 50, + limit: 50 + }, 'got a intersection'); + }); +}); +/*can-query-logic@1.1.6#compat/prop_tests/sort_test*/ +define('can-query-logic@1.1.6#compat/prop_tests/sort_test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + '../compat', + 'can-reflect' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var set = require('../compat'), props = set.props; + var canReflect = require('can-reflect'); + QUnit.module('can-set props.sort'); + test('set.difference', function () { + var prop = props.sort('sort'), res; + res = set.difference({ sort: 'foo' }, { completed: true }, prop); + deepEqual(res, set.UNDEFINABLE, 'diff should be true'); + res = set.difference({ completed: true }, { + completed: true, + sort: 'foo' + }, prop); + equal(res, set.EMPTY, 'the same except for sort'); + res = set.difference({ completed: true }, { sort: 'foo' }, prop); + equal(res, set.EMPTY, 'nothing in completed:true that isn\'t in everything'); + res = set.difference({ completed: true }, { + foo: 'bar', + sort: 'foo' + }, prop); + equal(res, set.UNDEFINABLE, 'we can diff, it exists, we don\'t know what it is though'); + }); + test('set.union', function () { + var prop = props.sort('sort'), res; + res = set.union({ sort: 'name' }, { completed: true }, prop); + deepEqual(res, {}, 'set / subset sort left'); + res = set.union({}, { + completed: true, + sort: 'name' + }, prop); + deepEqual(res, {}, 'set / subset sort right'); + res = set.union({ sort: 'name' }, { + completed: true, + sort: 'namer' + }, prop); + deepEqual(res, {}, 'set / subset both sorts'); + res = set.union({ completed: true }, { sort: 'foo' }, prop); + deepEqual(res, {}, 'subset / set'); + res = set.union({ + foo: 'bar', + sort: 'foo' + }, { foo: 'bar' }, prop); + deepEqual(res, { foo: 'bar' }, 'equal'); + res = set.union({ foo: 'bar' }, { + foo: 'zed', + sort: 'foo' + }, prop); + deepEqual(res, { + foo: [ + 'bar', + 'zed' + ] + }, 'values not equal'); + res = set.union({ + foo: 'bar', + sort: 'foo' + }, { name: 'A' }, prop); + deepEqual(res, set.UNDEFINABLE, 'values not equal'); + }); + test('set.union Array', function () { + var prop = props.sort('sort'); + var res = set.union({ + foo: [ + 'a', + 'b' + ], + sort: 'foo' + }, { + foo: [ + 'a', + 'c' + ] + }, prop); + deepEqual(res, { + foo: [ + 'a', + 'b', + 'c' + ] + }, 'set / subset'); + }); + test('set.count', function () { + ok(set.count({ sort: 'name' }) === Infinity, 'defaults to infinity'); + ok(set.count({ + foo: 'bar', + sort: 'foo' + }, {}) === Infinity, 'defaults to infinity'); + }); + test('set.intersection', function () { + var prop = props.sort('sort'), res; + res = set.intersection({}, { sort: 'name' }, prop); + deepEqual(res, {}, 'no sort if only one is sorted'); + res = set.intersection({ sort: 'name' }, { sort: 'name' }, prop); + deepEqual(res, { sort: 'name' }, 'equal'); + res = set.intersection({ type: 'new' }, { + sort: 'name', + userId: 5 + }, prop); + deepEqual(res, { + type: 'new', + userId: 5 + }, ''); + res = set.intersection({ + type: 'new', + sort: 'age' + }, { + sort: 'name', + userId: 5 + }, prop); + deepEqual(res, { + type: 'new', + userId: 5 + }, ''); + }); + test('set.intersection Array', function () { + var prop = props.sort('sort'); + var res = set.intersection({ + foo: [ + 'a', + 'b' + ], + sort: 'foo' + }, { + foo: [ + 'a', + 'c' + ] + }, prop); + deepEqual(res, { foo: 'a' }, 'intersection'); + }); + test('set.isSubset', function () { + var algebra = new set.Algebra(props.sort('sort'), set.props.ignore('foo'), set.props.ignore('bar'), set.props.ignore('kind'), set.props.ignore('count')); + ok(algebra.isSubset({ + type: 'FOLDER', + sort: 'thing' + }, { type: 'FOLDER' }), 'equal sets with sort on the left'); + ok(algebra.isSubset({ type: 'FOLDER' }, { + type: 'FOLDER', + sort: 'thing' + }), 'equal sets with sort on the right'); + ok(algebra.isSubset({ + type: 'FOLDER', + parentId: 5, + sort: 'thing' + }, { type: 'FOLDER' }), 'sub set with sort on the left'); + ok(algebra.isSubset({ + type: 'FOLDER', + parentId: 5 + }, { + type: 'FOLDER', + sort: 'thing' + }), 'sub set with sort on the right'); + ok(!algebra.isSubset({ + type: 'FOLDER', + sort: 'thing' + }, { + type: 'FOLDER', + parentId: 5 + }), 'wrong way with sort on the left'); + ok(!algebra.isSubset({ type: 'FOLDER' }, { + type: 'FOLDER', + parentId: 5, + sort: 'thing' + }), 'wrong way with sort on the right'); + ok(!algebra.isSubset({ + type: 'FOLDER', + parentId: 7, + sort: 'thing' + }, { + type: 'FOLDER', + parentId: 5 + }), 'different values with sort on the left'); + ok(!algebra.isSubset({ + type: 'FOLDER', + parentId: 7 + }, { + type: 'FOLDER', + parentId: 5, + sort: 'thing' + }), 'different values with sort on the right'); + }); + test('set.isSubset with range', function () { + var algebra = new set.Algebra(props.sort('sort'), props.rangeInclusive('start', 'end')); + var addSort = function (set, value) { + set.sort = value; + }; + var sort = { + left: function (setA, setB) { + addSort(setA, 'prop'); + }, + right: function (setA, setB) { + addSort(setB, 'prop'); + }, + same: function (setA, setB) { + addSort(setA, 'prop'); + addSort(setB, 'prop'); + }, + different: function (setA, setB) { + addSort(setA, 'propA'); + addSort(setB, 'propB'); + } + }; + var addRange = function (set, start, end) { + set.start = start; + set.end = end; + }; + var range = { + left: function (setA, setB) { + addRange(setA, 0, 9); + }, + right: function (setA, setB) { + addRange(setB, 0, 9); + }, + same: function (setA, setB) { + addRange(setA, 0, 9); + addRange(setB, 0, 9); + }, + superLeft: function (setA, setB) { + addRange(setA, 0, 9); + addRange(setB, 3, 7); + }, + superRight: function (setA, setB) { + addRange(setB, 0, 9); + addRange(setA, 3, 7); + } + }; + var sets = { + same: function (setA, setB) { + }, + superLeft: function (setA, setB) { + setB.type = 'apples'; + }, + superRight: function (setA, setB) { + setA.type = 'apples'; + } + }; + var make = function () { + var setA = {}, setB = {}; + canReflect.eachIndex(arguments, function (method) { + method(setA, setB); + }); + return { + left: setA, + right: setB + }; + }; + var assertSubset = function (methods, result) { + var sets = make.apply(null, methods); + equal(algebra.isSubset(sets.left, sets.right), result, JSON.stringify(sets.left) + ' \u2282 ' + JSON.stringify(sets.right) + ' = ' + result); + }; + assertSubset([ + sets.same, + range.same, + sort.different + ], undefined); + }); + test('set.index', function () { + var algebra = new set.Algebra(props.sort('sort')); + var index = algebra.index({ sort: 'name' }, [ + { + id: 1, + name: 'g' + }, + { + id: 2, + name: 'j' + }, + { + id: 3, + name: 'm' + }, + { + id: 4, + name: 's' + } + ], { name: 'k' }); + equal(index, 2); + }); + test('set.filterMembers (#14)', function () { + var algebra = new set.Algebra(props.sort('sort')); + var subset = algebra.filterMembers({ sort: 'name' }, {}, [ + { + id: 1, + name: 's' + }, + { + id: 2, + name: 'j' + }, + { + id: 3, + name: 'm' + }, + { + id: 4, + name: 'g' + } + ]); + deepEqual(subset, [ + { + id: 4, + name: 'g' + }, + { + id: 2, + name: 'j' + }, + { + id: 3, + name: 'm' + }, + { + id: 1, + name: 's' + } + ]); + }); + test('set.unionMembers', function () { + var algebra = new set.Algebra(props.sort('sort'), props.boolean('complete')); + var union = algebra.unionMembers({ + sort: 'name', + complete: true + }, { + sort: 'name', + complete: false + }, [ + { + id: 4, + name: 'g', + complete: true + }, + { + id: 3, + name: 'm', + complete: true + } + ], [ + { + id: 2, + name: 'j', + complete: false + }, + { + id: 1, + name: 's', + complete: false + } + ]); + deepEqual(union, [ + { + id: 4, + name: 'g', + complete: true + }, + { + id: 2, + name: 'j', + complete: false + }, + { + id: 3, + name: 'm', + complete: true + }, + { + id: 1, + name: 's', + complete: false + } + ]); + }); + test('set.union keeps sort', function () { + var algebra = new set.Algebra(props.sort('sort'), props.boolean('complete')); + var union = algebra.union({ + sort: 'name', + complete: true + }, { + sort: 'name', + complete: false + }); + deepEqual(union, { sort: 'name' }); + }); + test('paginated and sorted is subset (#17)', function () { + var algebra = new set.Algebra(props.sort('sort'), props.rangeInclusive('start', 'end')), res; + res = algebra.isSubset({ + start: 0, + end: 100, + sort: 'name' + }, { + start: 0, + end: 100, + sort: 'age' + }); + equal(res, undefined, 'parent:paginate+order child:paginate+order (different order)'); + res = algebra.isSubset({ + start: 0, + end: 100, + sort: 'name' + }, { sort: 'name' }); + equal(res, true, 'parent:order child:paginate+order'); + res = algebra.isSubset({ sort: 'name' }, { sort: 'name' }); + equal(res, true, 'parent:order child:order (same)'); + res = algebra.isSubset({ sort: 'name' }, { sort: 'age' }); + equal(res, true, 'parent:order child:order (different)'); + res = algebra.isSubset({ + start: 0, + end: 100 + }, { sort: 'name' }); + equal(res, true, 'parent:order child:paginate'); + res = algebra.isSubset({ + start: 0, + end: 100, + sort: 'age' + }, { sort: 'name' }); + equal(res, true, 'parent:order child:paginate+order'); + res = algebra.isSubset({ + start: 0, + end: 100, + sort: 'name' + }, { + start: 0, + end: 100 + }); + equal(res, undefined, 'parent:paginate child:paginate+order'); + res = algebra.isSubset({ sort: 'name' }, { + start: 0, + end: 100 + }); + equal(res, false, 'parent:paginate child:order (same)'); + res = algebra.isSubset({ + start: 0, + end: 100, + sort: 'name' + }, {}); + equal(res, true, 'parent:-- child:paginate+order'); + res = algebra.isSubset({ + start: 10, + end: 90, + sort: 'name' + }, { + start: 0, + end: 100, + sort: 'name' + }); + equal(res, true, 'child in smaller range, same sort'); + res = algebra.isSubset({ + start: 10, + end: 90, + sort: 'name' + }, { + start: 0, + end: 100, + sort: 'age' + }); + equal(res, undefined, 'child in smaller range, but different sort'); + }); +}); +/*can-query-logic@1.1.6#compat/prop_tests/translate_test*/ +define('can-query-logic@1.1.6#compat/prop_tests/translate_test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + '../../src/set', + '../compat' +], function (require, exports, module) { + require('steal-qunit'); + var querySet = require('../../src/set'); + var set = require('../compat'); + var ignoreProp = function () { + return true; + }; + QUnit.module('can-set set.Translate - nested where'); + QUnit.test('set.equal', function () { + var algebra = new set.Algebra(new set.Translate('where', '$where'), set.props.ignore('count')); + var res; + res = algebra.isEqual({ $where: { type: 'FOLDER' } }, { + $where: { + type: 'FOLDER', + count: 5 + } + }); + ok(res, 'count ignored'); + res = algebra.isEqual({ $where: { type: 'FOLDER' } }, { $where: { type: 'FOLDER' } }); + ok(res, 'folder case ignored'); + }); + QUnit.test('set.isSubset', function () { + var algebra = new set.Algebra(new set.Translate('where', '$where'), set.props.ignore('foo'), set.props.ignore('bar'), set.props.ignore('kind'), set.props.ignore('count')); + var res; + res = algebra.isSubset({ $where: { type: 'FOLDER' } }, { $where: { type: 'FOLDER' } }); + ok(res, 'equal sets'); + res = algebra.isSubset({ + $where: { + type: 'FOLDER', + parentId: 5 + } + }, { $where: { type: 'FOLDER' } }); + ok(res, 'sub set'); + res = algebra.isSubset({ $where: { type: 'FOLDER' } }, { + $where: { + type: 'FOLDER', + parentId: 5 + } + }); + ok(!res, 'wrong way'); + res = algebra.isSubset({ + $where: { + type: 'FOLDER', + parentId: 7 + } + }, { + $where: { + type: 'FOLDER', + parentId: 5 + } + }); + ok(!res, 'different values'); + res = algebra.isSubset({ + $where: { + type: 'FOLDER', + count: 5 + } + }, { $where: { type: 'FOLDER' } }); + ok(res, 'count ignored'); + res = algebra.isSubset({ + $where: { + type: 'FOLDER', + category: 'tree' + } + }, { + $where: { + type: 'FOLDER', + foo: true, + bar: true + } + }); + ok(res, 'understands a subset'); + res = algebra.isSubset({ + $where: { + type: 'FOLDER', + foo: true, + bar: true + } + }, { + $where: { + type: 'FOLDER', + kind: 'tree' + } + }); + ok(res, 'ignores nulls'); + }); + test('set.isProperSubset', function () { + var algebra = new set.Algebra(new set.Translate('where', '$where')); + equal(algebra.isProperSubset({ $where: { foo: 'bar' } }, { $where: {} }), true); + equal(algebra.isProperSubset({ $where: {} }, { $where: {} }), false); + equal(algebra.isProperSubset({ $where: {} }, { $where: { foo: 'bar' } }), false); + }); + test('set.difference', function () { + var algebra = new set.Algebra(new set.Translate('where', '$where')); + var res = algebra.difference({ $where: {} }, { $where: { completed: true } }); + equal(res, querySet.UNDEFINABLE, 'diff should be true'); + res = algebra.difference({ $where: { completed: true } }, { $where: { completed: true } }); + equal(res, querySet.EMPTY); + res = algebra.difference({ $where: { completed: true } }, { $where: {} }); + equal(res, querySet.EMPTY); + res = algebra.difference({ $where: { completed: true } }, { $where: { userId: 5 } }); + equal(res, querySet.UNDEFINABLE); + }); + test('set.union', function () { + var algebra = new set.Algebra(new set.Translate('where', '$where')); + var res = algebra.union({ $where: {} }, { $where: { completed: true } }); + deepEqual(res, {}, 'set / subset'); + res = algebra.union({ $where: { completed: true } }, { $where: {} }); + deepEqual(res, {}, 'subset / set'); + res = algebra.union({ $where: { foo: 'bar' } }, { $where: { foo: 'bar' } }); + deepEqual(res, { $where: { foo: 'bar' } }, 'equal'); + res = algebra.union({ $where: { foo: 'bar' } }, { $where: { foo: 'zed' } }); + deepEqual(res, { + $where: { + foo: [ + 'bar', + 'zed' + ] + } + }, 'values not equal'); + res = algebra.union({ $where: { foo: 'bar' } }, { $where: { name: 'A' } }); + deepEqual(res, querySet.UNDEFINABLE, 'values not equal'); + }); + test('set.union Array', function () { + var algebra = new set.Algebra(new set.Translate('where', '$where')); + var res = algebra.union({ + $where: { + foo: [ + 'a', + 'b' + ] + } + }, { + $where: { + foo: [ + 'a', + 'c' + ] + } + }); + deepEqual(res, { + $where: { + foo: [ + 'a', + 'b', + 'c' + ] + } + }, 'set / subset'); + }); + test('set.intersection', function () { + var algebra = new set.Algebra(new set.Translate('where', '$where')), res; + res = algebra.intersection({ $where: {} }, { $where: { completed: true } }); + deepEqual(res, { $where: { completed: true } }, 'set / subset'); + res = algebra.intersection({ $where: { completed: true } }, { $where: {} }); + deepEqual(res, { $where: { completed: true } }, 'subset / set'); + res = algebra.intersection({ $where: { foo: 'bar' } }, { $where: { foo: 'bar' } }); + deepEqual(res, { $where: { foo: 'bar' } }, 'equal'); + res = algebra.intersection({ $where: { foo: 'bar' } }, { $where: { foo: 'zed' } }); + deepEqual(res, querySet.EMPTY, 'values not equal'); + res = algebra.intersection({ $where: { foo: 'bar' } }, { $where: { completed: true } }); + deepEqual(res, { + $where: { + foo: 'bar', + completed: true + } + }, 'intersection should combine definitions'); + }); + test('set.intersection Array', function () { + var algebra = new set.Algebra(new set.Translate('where', '$where')); + var res = algebra.intersection({ + $where: { + foo: [ + 'a', + 'b' + ] + } + }, { + $where: { + foo: [ + 'a', + 'c' + ] + } + }); + deepEqual(res, { $where: { foo: 'a' } }, 'intersection'); + }); + test('set.has', function () { + var algebra = new set.Algebra(new set.Translate('where', '$where'), set.props.ignore('count'), set.props.ignore('foo'), set.props.ignore('bar'), set.props.ignore('kind')); + ok(algebra.isMember({ $where: { someId: 5 } }, { + someId: 5, + name: 'foo' + }), 'contains'); + var res; + res = algebra.isMember({ $where: { type: 'FOLDER' } }, { type: 'FOLDER' }); + ok(res, 'equal sets'); + res = algebra.isMember({ + $where: { + type: 'FOLDER', + parentId: 5 + } + }, { type: 'FOLDER' }); + equal(res, false, 'doesnt match'); + res = algebra.isMember({ $where: { type: 'FOLDER' } }, { + type: 'FOLDER', + parentId: 5 + }); + ok(true, 'is a subset'); + res = algebra.isMember({ + $where: { + type: 'FOLDER', + parentId: 7 + } + }, { + type: 'FOLDER', + parentId: 5 + }); + ok(!res, 'different values'); + res = algebra.isMember({ + $where: { + type: 'FOLDER', + count: 5 + } + }, { type: 'FOLDER' }, { count: ignoreProp }); + ok(res, 'count ignored'); + res = algebra.isMember({ + $where: { + type: 'FOLDER', + kind: 'tree' + } + }, { + type: 'FOLDER', + foo: true, + bar: true + }); + ok(res, 'understands a subset'); + res = algebra.isMember({ + $where: { + type: 'FOLDER', + foo: true, + bar: true + } + }, { + type: 'FOLDER', + kind: 'tree' + }); + ok(res, 'ignores nulls'); + }); +}); +/*can-query-logic@1.1.6#compat/compat-test*/ +define('can-query-logic@1.1.6#compat/compat-test', [ + 'require', + 'exports', + 'module', + './prop_tests/boolean_test', + './prop_tests/enum_test', + './prop_tests/id_test', + './prop_tests/rangeInclusive_test', + './prop_tests/offsetLimit_test', + './prop_tests/sort_test', + './prop_tests/translate_test' +], function (require, exports, module) { + require('./prop_tests/boolean_test'); + require('./prop_tests/enum_test'); + require('./prop_tests/id_test'); + require('./prop_tests/rangeInclusive_test'); + require('./prop_tests/offsetLimit_test'); + require('./prop_tests/sort_test'); + require('./prop_tests/translate_test'); +}); +/*can-query-logic@1.1.6#test/special-comparison-logic-test*/ +define('can-query-logic@1.1.6#test/special-comparison-logic-test', [ + 'require', + 'exports', + 'module', + '../can-query-logic', + 'steal-qunit', + 'can-reflect', + 'can-symbol' +], function (require, exports, module) { + var QueryLogic = require('../can-query-logic'); + var QUnit = require('steal-qunit'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + QUnit.module('can-query-logic special comparison logic'); + QUnit.test('where to filter', function () { + var todoQueryLogic = new QueryLogic({}, { + toQuery: function (params) { + var where = params.where; + delete params.where; + params.filter = where; + return params; + }, + toParams: function (query) { + var where = query.filter; + delete query.filter; + query.where = where; + return query; + } + }); + var q1 = { where: { first: 'FIRST' } }, q2 = { where: { second: 'SECOND' } }; + var q3 = todoQueryLogic.intersection(q1, q2); + QUnit.deepEqual(q3, { + where: { + first: 'FIRST', + second: 'SECOND' + } + }, 'got intersection'); + }); + var stringIncludes = function (strA, strB) { + return strA.indexOf(strB) >= 0; + }; + QUnit.test('Searchable string', function () { + function SearchableStringSet(value) { + this.value = value; + } + canReflect.assignSymbols(SearchableStringSet.prototype, { + 'can.isMember': function (value) { + return stringIncludes(value, this.value); + }, + 'can.serialize': function () { + return this.value; + } + }); + QueryLogic.defineComparison(SearchableStringSet, SearchableStringSet, { + union: function (searchA, searchB) { + if (stringIncludes(searchA.value, searchB.value)) { + return searchB; + } + if (stringIncludes(searchB.value, searchA.value)) { + return searchA; + } + return new QueryLogic.ValuesOr([ + searchA, + searchB + ]); + }, + intersection: function (searchA, searchB) { + if (stringIncludes(searchA.value, searchB.value)) { + return searchA; + } + if (stringIncludes(searchB.value, searchA.value)) { + return searchB; + } + return QueryLogic.UNDEFINABLE; + }, + difference: function (searchA, searchB) { + if (stringIncludes(searchA.value, searchB.value)) { + return QueryLogic.EMPTY; + } + if (stringIncludes(searchB.value, searchA.value)) { + return QueryLogic.UNDEFINABLE; + } + return QueryLogic.UNDEFINABLE; + } + }); + function SearchableString() { + } + SearchableString[canSymbol.for('can.SetType')] = SearchableStringSet; + var todoQueryLogic = new QueryLogic({ keys: { name: SearchableString } }); + var res = todoQueryLogic.isSubset({ filter: { name: 'beat' } }, { filter: { name: 'eat' } }); + QUnit.equal(res, true, 'is subset'); + res = todoQueryLogic.isSubset({ filter: { name: 'eat' } }, { filter: { name: 'beat' } }); + QUnit.equal(res, false, 'not subset'); + var hydrated = todoQueryLogic.hydrate({ filter: { name: 'eat' } }); + QUnit.deepEqual(hydrated.filter, new QueryLogic.KeysAnd({ name: new SearchableStringSet('eat') }), 'hydrated right'); + res = todoQueryLogic.union({ filter: { name: 'eat' } }, { filter: { name: 'foo' } }); + QUnit.deepEqual(res, { + filter: { + name: [ + 'eat', + 'foo' + ] + } + }); + QUnit.ok(todoQueryLogic.isMember({ filter: { name: 'eat' } }, { + id: 1, + name: 'eat beans' + }), 'isMember true'); + QUnit.notOk(todoQueryLogic.isMember({ filter: { name: 'eat' } }, { + id: 1, + name: 'foo bar' + }), 'isMember false'); + }); + QUnit.test('value type', function () { + function DateStringSet(dateStr) { + this.dateStr = dateStr; + } + DateStringSet.prototype.valueOf = function () { + return new Date(this.dateStr).valueOf(); + }; + canReflect.assignSymbols(DateStringSet.prototype, { + 'can.serialize': function () { + return this.dateStr; + } + }); + function DateString() { + } + canReflect.assignSymbols(DateString, { 'can.SetType': DateStringSet }); + var queryLogic = new QueryLogic({ keys: { date: DateString } }); + var oct20_1982 = new Date(1982, 9, 20), date90s = new Date(1990, 0, 1); + var result = queryLogic.filterMembers({ filter: { date: { $gt: oct20_1982.toString() } } }, [ + { + id: 1, + date: new Date(1981, 9, 20).toString() + }, + { + id: 2, + date: new Date(1982, 9, 20).toString() + }, + { + id: 3, + date: new Date(1983, 9, 20).toString() + }, + { + id: 4, + date: new Date(1984, 9, 20).toString() + } + ]); + QUnit.deepEqual(result.map(function (item) { + return item.id; + }), [ + 3, + 4 + ], 'filtered correctly'); + var union = queryLogic.union({ filter: { date: [oct20_1982.toString()] } }, { filter: { date: [date90s.toString()] } }); + QUnit.deepEqual(union, { + filter: { + date: { + $in: [ + oct20_1982.toString(), + date90s.toString() + ] + } + } + }, 'union of 2 dates works correctly'); + result = queryLogic.filterMembers({ sort: 'date' }, [ + { + id: 2, + date: new Date(1982, 9, 20).toString() + }, + { + id: 1, + date: new Date(1981, 9, 20).toString() + }, + { + id: 4, + date: new Date(1984, 9, 20).toString() + }, + { + id: 3, + date: new Date(1983, 9, 20).toString() + } + ]); + var ids = result.map(function (item) { + return item.id; + }); + QUnit.deepEqual(ids, [ + 1, + 2, + 3, + 4 + ], 'sorted correctly'); + var index = queryLogic.index({ sort: 'date' }, [ + { + id: 1, + date: new Date(2018, 4, 20).toString() + }, + { + id: 2, + date: new Date(2018, 4, 21).toString() + }, + { + id: 3, + date: new Date(2018, 4, 22).toString() + }, + { + id: 4, + date: new Date(2018, 4, 23).toString() + } + ], { + id: 4, + date: new Date(2018, 4, 24).toString() + }); + QUnit.equal(index, 4, 'added at the end'); + }); +}); +/*can-query-logic@1.1.6#test/make-enum-logic-test*/ +define('can-query-logic@1.1.6#test/make-enum-logic-test', [ + 'require', + 'exports', + 'module', + 'can-query-logic', + 'can-reflect', + '../src/types/make-enum' +], function (require, exports, module) { + var QueryLogic = require('can-query-logic'); + var canReflect = require('can-reflect'); + var makeEnum = require('../src/types/make-enum'); + QUnit.module('can-query-logic with makeEnum'); + function Color() { + } + makeEnum(Color, [ + 'red', + 'green', + 'blue' + ]); + var TODO = canReflect.assignSymbols({}, { + 'can.getSchema': function () { + return { + kind: 'record', + identity: ['id'], + keys: { + id: Number, + points: Number, + status: Color, + complete: Boolean, + name: String + } + }; + } + }); + var algebra = new QueryLogic(TODO); + QUnit.test('union - enum', function () { + var unionResult = algebra.union({ + filter: { + name: 'Justin', + status: 'red' + } + }, { + filter: { + name: 'Justin', + status: 'green' + } + }); + QUnit.deepEqual(unionResult, { + filter: { + name: 'Justin', + status: [ + 'red', + 'green' + ] + } + }); + }); + QUnit.test('automatic enum', function () { + var MaybeBoolean = canReflect.assignSymbols({}, { + 'can.new': function (val) { + if (val == null) { + return val; + } + if (val === 'false' || val === '0' || !val) { + return false; + } + return true; + }, + 'can.getSchema': function () { + return { + type: 'Or', + values: [ + true, + false, + undefined, + null + ] + }; + } + }); + var queryLogic = new QueryLogic({ + identity: ['id'], + keys: { complete: MaybeBoolean } + }); + var res; + res = queryLogic.difference({}, { filter: { complete: true } }); + QUnit.deepEqual(res, { + filter: { + complete: [ + false, + undefined, + null + ] + } + }, 'enum works'); + }); + QUnit.test('makeEnum from homepage with schema type', function () { + var Status = canReflect.assignSymbols({}, { + 'can.new': function (val) { + return val; + }, + 'can.getSchema': function () { + return { + type: 'Or', + values: [ + 'new', + 'assigned', + 'complete' + ] + }; + } + }); + var todoLogic = new QueryLogic({ + identity: ['id'], + keys: { status: Status } + }); + var unionQuery = todoLogic.union({ + filter: { + status: [ + 'new', + 'assigned' + ] + } + }, { filter: { status: 'complete' } }); + QUnit.deepEqual(unionQuery, {}); + }); + QUnit.test('makeEnum from homepage', function () { + var Status = QueryLogic.makeEnum([ + 'new', + 'assigned', + 'complete' + ]); + var todoLogic = new QueryLogic({ + identity: ['id'], + keys: { status: Status } + }); + var unionQuery = todoLogic.union({ + filter: { + status: [ + 'new', + 'assigned' + ] + } + }, { filter: { status: 'complete' } }); + QUnit.deepEqual(unionQuery, {}); + }); +}); +/*can-query-logic@1.1.6#test/maybe-type-test*/ +define('can-query-logic@1.1.6#test/maybe-type-test', [ + 'require', + 'exports', + 'module', + '../can-query-logic', + 'steal-qunit', + 'can-reflect' +], function (require, exports, module) { + var QueryLogic = require('../can-query-logic'); + var QUnit = require('steal-qunit'); + var canReflect = require('can-reflect'); + QUnit.module('can-query-logic with maybe type'); + QUnit.test('basics', function () { + var MaybeNumber = canReflect.assignSymbols({}, { + 'can.new': function (val) { + if (val == null) { + return val; + } + return +val; + }, + 'can.getSchema': function () { + return { + type: 'Or', + values: [ + Number, + undefined, + null + ] + }; + } + }); + var res; + var todoQueryLogic = new QueryLogic({ keys: { age: MaybeNumber } }); + var unionized = todoQueryLogic.union({ filter: { age: 7 } }, { filter: { age: '07' } }); + QUnit.deepEqual(unionized, { filter: { age: 7 } }, 'string numbers are converted to numbers'); + }); + QUnit.test('MaybeDate', function () { + function toDate(str) { + var type = typeof str; + if (type === 'string') { + str = Date.parse(str); + return isNaN(str) ? null : new Date(str); + } else if (type === 'number') { + return new Date(str); + } else { + return str; + } + } + function DateStringSet(dateStr) { + this.setValue = dateStr; + var date = toDate(dateStr); + this.value = date == null ? date : date.getTime(); + } + DateStringSet.prototype.valueOf = function () { + return this.value; + }; + canReflect.assignSymbols(DateStringSet.prototype, { + 'can.serialize': function () { + return this.setValue; + } + }); + var MaybeDate = canReflect.assignSymbols({}, { + 'can.new': toDate, + 'can.getSchema': function () { + return { + type: 'Or', + values: [ + Date, + undefined, + null + ] + }; + }, + 'can.ComparisonSetType': DateStringSet + }); + var res; + var todoQueryLogic = new QueryLogic({ keys: { due: MaybeDate } }); + var store = [ + { + id: 1, + due: null + }, + { + id: 2, + due: new Date(2001, 0, 1).toString() + }, + { + id: 3, + due: new Date(2000, 0, 1).toString() + }, + { + id: 4, + due: null + } + ]; + var results = todoQueryLogic.filterMembers({ sort: 'due' }, store); + QUnit.deepEqual(results, [ + { + id: 1, + due: null + }, + { + id: 4, + due: null + }, + { + id: 3, + due: new Date(2000, 0, 1).toString() + }, + { + id: 2, + due: new Date(2001, 0, 1).toString() + } + ]); + }); +}); +/*can-query-logic@1.1.6#can-query-logic-test*/ +define('can-query-logic@1.1.6#can-query-logic-test', [ + 'require', + 'exports', + 'module', + './src/set-test', + './src/types/make-real-number-range-inclusive-test', + './src/types/comparisons-test', + './src/types/and-or-not-test', + './src/types/values-or-test', + './src/types/basic-query-sorting-test', + './src/types/basic-query-filter-from-test', + './src/types/basic-query-merge-test', + './src/serializers/basic-query-test', + './src/serializers/comparisons-test', + './src/types/make-maybe-test', + './src/types/make-enum-test', + './compat/compat-test', + './test/special-comparison-logic-test', + './test/make-enum-logic-test', + './test/maybe-type-test', + 'steal-qunit', + 'can-query-logic', + 'can-reflect' +], function (require, exports, module) { + require('./src/set-test'); + require('./src/types/make-real-number-range-inclusive-test'); + require('./src/types/comparisons-test'); + require('./src/types/and-or-not-test'); + require('./src/types/values-or-test'); + require('./src/types/basic-query-sorting-test'); + require('./src/types/basic-query-filter-from-test'); + require('./src/types/basic-query-merge-test'); + require('./src/serializers/basic-query-test'); + require('./src/serializers/comparisons-test'); + require('./src/types/make-maybe-test'); + require('./src/types/make-enum-test'); + require('./compat/compat-test'); + require('./test/special-comparison-logic-test'); + require('./test/make-enum-logic-test'); + require('./test/maybe-type-test'); + var QUnit = require('steal-qunit'); + var QueryLogic = require('can-query-logic'); + var canReflect = require('can-reflect'); + var algebra = new QueryLogic(); + QUnit.module('can-query-logic'); + QUnit.test('union', function () { + var unionResult = algebra.union({ filter: { name: 'Ramiya' } }, { filter: { name: 'Bohdi' } }); + QUnit.deepEqual(unionResult, { + filter: { + name: { + $in: [ + 'Ramiya', + 'Bohdi' + ] + } + } + }); + }); + QUnit.test('difference', function () { + var differenceResult = algebra.difference({ + filter: { + name: { + $in: [ + 'Ramiya', + 'Bohdi' + ] + } + } + }, { filter: { name: 'Bohdi' } }); + QUnit.deepEqual(differenceResult, { filter: { name: 'Ramiya' } }); + }); + QUnit.test('subset', function () { + var subsetResult = algebra.isSubset({ filter: { name: 'Bohdi' } }, { + filter: { + name: { + $in: [ + 'Ramiya', + 'Bohdi' + ] + } + } + }); + QUnit.deepEqual(subsetResult, true); + }); + QUnit.test('isMember', function () { + var hasResult = algebra.isMember({ filter: { name: 'Bohdi' } }, { name: 'Bohdi' }); + QUnit.deepEqual(hasResult, true); + }); + QUnit.test('filterMembers basics', function () { + var subset = algebra.filterMembers({ + filter: { + name: { + $in: [ + 'Bohdi', + 'Ramiya' + ] + } + } + }, {}, [ + { name: 'Bohdi' }, + { name: 'Ramiya' }, + { name: 'Payal' }, + { name: 'Justin' } + ]); + QUnit.deepEqual(subset, [ + { name: 'Bohdi' }, + { name: 'Ramiya' } + ]); + subset = algebra.filterMembers({ + filter: { + name: { + $in: [ + 'Payal', + 'Ramiya', + 'Justin' + ] + } + }, + page: { + start: '1', + end: '2' + } + }, {}, [ + { name: 'Bohdi' }, + { name: 'Ramiya' }, + { name: 'Payal' }, + { name: 'Justin' } + ]); + QUnit.deepEqual(subset, [ + { name: 'Payal' }, + { name: 'Justin' } + ]); + }); + QUnit.test('unionMembers basics', function () { + var union = algebra.unionMembers({ filter: { name: 'Bohdi' } }, { filter: { name: 'Ramiya' } }, [{ + name: 'Bohdi', + id: 1 + }], [{ + name: 'Ramiya', + id: 2 + }]); + QUnit.deepEqual(union, [ + { + name: 'Bohdi', + id: 1 + }, + { + name: 'Ramiya', + id: 2 + } + ]); + }); + QUnit.test('count basics', function () { + QUnit.equal(algebra.count({}), Infinity); + QUnit.equal(algebra.count({ + page: { + start: 1, + end: 2 + } + }), 2); + }); + QUnit.test('index basics', function () { + var index = algebra.index({ sort: 'name' }, [ + { + id: 1, + name: 'g' + }, + { + id: 2, + name: 'j' + }, + { + id: 3, + name: 'm' + }, + { + id: 4, + name: 's' + } + ], { name: 'k' }); + equal(index, 2); + index = algebra.index({ sort: '-name' }, [ + { + id: 1, + name: 'g' + }, + { + id: 2, + name: 'j' + }, + { + id: 3, + name: 'm' + }, + { + id: 4, + name: 's' + } + ].reverse(), { name: 'k' }); + equal(index, 2); + index = algebra.index({}, [ + { + id: 1, + name: 'g' + }, + { + id: 2, + name: 'j' + }, + { + id: 3, + name: 'm' + }, + { + id: 4, + name: 's' + } + ], { + id: 0, + name: 'k' + }); + equal(index, 0); + index = algebra.index({}, [ + { + id: 1, + name: 'g' + }, + { + id: 2, + name: 'j' + }, + { + id: 3, + name: 'm' + }, + { + id: 4, + name: 's' + } + ], { name: 'k' }); + equal(index, undefined, 'no value if no id'); + var TODO_id = canReflect.assignSymbols({}, { + 'can.getSchema': function () { + return { + kind: 'record', + identity: ['_id'], + keys: { + id: Number, + points: Number, + complete: Boolean, + name: String + } + }; + } + }); + var algebra2 = new QueryLogic(TODO_id); + index = algebra2.index({}, [ + { + id: 1, + _id: 0 + }, + { + id: 2, + _id: 1 + }, + { + id: 3, + _id: 3 + }, + { + id: 4, + _id: 4 + } + ], { + id: 0, + _id: 2 + }); + equal(index, 2); + }); + QUnit.test('filterMembers with reverse sort', function () { + var sortedMembers = algebra.filterMembers({ sort: '-name' }, [ + { + id: 1, + name: 'a' + }, + { + id: 2, + name: 'z' + }, + { + id: 3, + name: 'f' + }, + { + id: 4, + name: 's' + } + ]); + QUnit.deepEqual(sortedMembers, [ + { + id: 2, + name: 'z' + }, + { + id: 4, + name: 's' + }, + { + id: 3, + name: 'f' + }, + { + id: 1, + name: 'a' + } + ]); + }); + QUnit.test('isPaginated, removePagination', function (assert) { + assert.equal(algebra.isPaginated({}), false, 'universe is not paginated'); + assert.equal(algebra.isPaginated({ filter: { foo: 'bar' } }), false, 'filter is not paginated'); + assert.equal(algebra.isPaginated({ sort: 'bar' }), false, 'sort is not paginated'); + assert.equal(algebra.isPaginated({ + page: { + start: 1, + end: 2 + } + }), true, 'page is paginated'); + assert.deepEqual(algebra.removePagination({}), {}, 'removePagination universe'); + assert.deepEqual(algebra.removePagination({ filter: { foo: 'bar' } }), { filter: { foo: 'bar' } }, 'removePagination filter'); + assert.deepEqual(algebra.removePagination({ sort: 'bar' }), { sort: 'bar' }, 'removePagination sort'); + assert.deepEqual(algebra.removePagination({ + page: { + start: 1, + end: 2 + } + }), {}, 'removePagination page'); + }); + QUnit.test('Value returned by makeEnum is constructorLike', function (assert) { + var Status = QueryLogic.makeEnum([ + 'new', + 'preparing', + 'delivery', + 'delivered' + ]); + var pass = canReflect.isConstructorLike(Status); + assert.ok(pass, 'Status is constructor like'); + }); + QUnit.test('can call low-level APIs from the outside', function () { + var gt1 = new QueryLogic.GreaterThan(1); + var lte1 = new QueryLogic.LessThanEqual(1); + QUnit.equal(QueryLogic.intersection(gt1, lte1), QueryLogic.EMPTY); + var isGtJustinAndGt35 = new QueryLogic.KeysAnd({ + name: new QueryLogic.GreaterThan('Justin'), + age: new QueryLogic.GreaterThan(35) + }); + var isGt25 = new QueryLogic.KeysAnd({ age: new QueryLogic.GreaterThan(25) }); + QUnit.deepEqual(QueryLogic.union(isGtJustinAndGt35, isGt25), isGt25, 'fewer clauses'); + }); +}); +/*can-value@1.1.0#test/test*/ +define('can-value@1.1.0#test/test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + '../can-value', + 'can-reflect', + 'can-reflect-dependencies', + 'can-simple-map' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var canValue = require('../can-value'); + var canReflect = require('can-reflect'); + var canReflectDeps = require('can-reflect-dependencies'); + var SimpleMap = require('can-simple-map'); + var onlyDevTest = steal.isEnv('production') ? QUnit.skip : QUnit.test; + var supportsFunctionNames = function () { + var fn = function () { + }; + return !!fn.name; + }(); + QUnit.module('can-value'); + QUnit.test('bind method works', function () { + var outer = new SimpleMap({ inner: new SimpleMap({ key: 'hello' }) }); + var observable = canValue.bind(outer, 'inner.key'); + QUnit.equal(canReflect.getValue(observable), 'hello', 'getting works'); + canReflect.setValue(observable, 'aloha'); + QUnit.equal(outer.get('inner').get('key'), 'aloha', 'setting works'); + }); + QUnit.test('from method works', function () { + var outer = { inner: { key: 'hello' } }; + var observation = canValue.from(outer, 'inner.key'); + QUnit.equal(canReflect.getValue(observation), 'hello', 'getting works'); + var errorThrown; + try { + canReflect.setValue(observation, 'aloha'); + } catch (error) { + errorThrown = error; + } + QUnit.ok(errorThrown instanceof Error, 'setting doesn\u2019t work'); + }); + if (supportsFunctionNames) { + onlyDevTest('from method returns an observation with a helpful name', function () { + var outer = { inner: { key: 'hello' } }; + var observation = canValue.from(outer, 'inner.key'); + QUnit.equal(canReflect.getName(observation), 'Observation>', 'observation has the correct name'); + }); + } + onlyDevTest('from method observable has dependency data', function (assert) { + var outer = new SimpleMap({ inner: new SimpleMap({ key: 'hello' }) }); + var observation = canValue.from(outer, 'inner.key'); + canReflect.onValue(observation, function () { + }); + var observationDepData = canReflectDeps.getDependencyDataOf(observation); + assert.deepEqual(observationDepData, { + whatChangesMe: { + derive: { + keyDependencies: new Map([ + [ + outer, + new Set(['inner']) + ], + [ + outer.get('inner'), + new Set(['key']) + ] + ]) + } + } + }, 'the observation has the correct mutation dependencies'); + var innerDepData = canReflectDeps.getDependencyDataOf(outer, 'inner'); + assert.deepEqual(innerDepData, { whatIChange: { derive: { valueDependencies: new Set([observation]) } } }, 'outer.inner has the correct mutation dependencies'); + var keyDepData = canReflectDeps.getDependencyDataOf(outer.get('inner'), 'key'); + assert.deepEqual(keyDepData, { whatIChange: { derive: { valueDependencies: new Set([observation]) } } }, 'outer.inner.key has the correct mutation dependencies'); + }); + QUnit.test('with method works', function () { + var observable = canValue.with(15); + QUnit.equal(canReflect.getValue(observable), 15, 'getting works'); + canReflect.setValue(observable, 22); + QUnit.equal(canReflect.getValue(observable), 22, 'setting works'); + }); + QUnit.test('returnedBy method works', function () { + var person = new SimpleMap({ + first: 'Grace', + last: 'Murray' + }); + var observable = canValue.returnedBy(function () { + return person.get('first') + ' ' + person.get('last'); + }); + QUnit.equal(canReflect.getValue(observable), 'Grace Murray', 'getting works'); + person.set('last', 'Hopper'); + QUnit.equal(canReflect.getValue(observable), 'Grace Hopper', 'setting works'); + }); + QUnit.test('returnedBy(getter(lastSet)) method works', function () { + var person = new SimpleMap({ + first: 'Grace', + last: 'Murray' + }); + var observable = canValue.returnedBy(function (lastSet) { + return person.get('first') + lastSet + person.get('last'); + }, null, ' '); + QUnit.equal(canReflect.getValue(observable), 'Grace Murray', 'getting works'); + person.set('last', 'Hopper'); + QUnit.equal(canReflect.getValue(observable), 'Grace Hopper', 'setting dep works'); + observable.value = ' J '; + QUnit.equal(observable.value, 'Grace J Hopper', 'setting works'); + }); + QUnit.test('to method works', function () { + var outer = { inner: { key: 'hello' } }; + var setProp = canValue.to(outer, 'inner.key'); + QUnit.equal(canReflect.getValue(setProp), setProp, 'getting the value doesn\u2019t work'); + canReflect.setValue(setProp, 'aloha'); + QUnit.equal(outer.inner.key, 'aloha', 'setting works'); + }); + onlyDevTest('to method observable has dependency data', function (assert) { + var outer = new SimpleMap({ inner: new SimpleMap({ key: 'hello' }) }); + var observable = canValue.to(outer, 'inner.key'); + canReflect.onValue(observable, function () { + }); + var innerDepData = canReflectDeps.getDependencyDataOf(outer, 'inner'); + assert.notOk(innerDepData, 'outer.inner has no mutation dependencies'); + var keyDepData = canReflectDeps.getDependencyDataOf(outer.get('inner'), 'key'); + assert.deepEqual(keyDepData, { + whatChangesMe: { + mutate: { + keyDependencies: new Map(), + valueDependencies: new Set([observable]) + } + } + }, 'outer.inner.key has the correct mutation dependencies'); + var observableDepData = canReflectDeps.getDependencyDataOf(observable); + assert.deepEqual(observableDepData, { + whatIChange: { + mutate: { + keyDependencies: new Map([[ + outer.get('inner'), + new Set(['key']) + ]]) + } + } + }, 'observable has the correct mutation dependencies'); + }); + QUnit.test('to method observable works when the keys change', function (assert) { + var originalInner = new SimpleMap({ key: 'hello' }); + var outer = new SimpleMap({ inner: originalInner }); + var observable = canValue.to(outer, 'inner.key'); + var newInner = new SimpleMap({ key: 'aloha' }); + outer.set('inner', newInner); + canReflect.setValue(observable, 'ciao'); + QUnit.equal(newInner.get('key'), 'ciao', 'setting works after changing the inner object'); + QUnit.equal(originalInner.get('key'), 'hello', 'the original inner object is untouched'); + }); + onlyDevTest('to method observable works when the keys change - dependency data', function (assert) { + var originalInner = new SimpleMap({ key: 'hello' }); + var outer = new SimpleMap({ inner: originalInner }); + var observable = canValue.to(outer, 'inner.key'); + canReflect.onValue(observable, function () { + }); + var newInner = new SimpleMap({ key: 'aloha' }); + outer.set('inner', newInner); + canReflect.setValue(observable, 'ciao'); + var innerDepData = canReflectDeps.getDependencyDataOf(outer, 'inner'); + assert.notOk(innerDepData, 'outer.inner has no mutation dependencies'); + var originalKeyDepData = canReflectDeps.getDependencyDataOf(originalInner, 'key'); + assert.notOk(originalKeyDepData, 'original outer.inner.key no longer has any dependencies'); + var newKeyDepData = canReflectDeps.getDependencyDataOf(newInner, 'key'); + assert.deepEqual(newKeyDepData, { + whatChangesMe: { + mutate: { + keyDependencies: new Map(), + valueDependencies: new Set([observable]) + } + } + }, 'outer.inner.key has the correct mutation dependencies'); + var observableDepData = canReflectDeps.getDependencyDataOf(observable); + assert.deepEqual(observableDepData, { + whatIChange: { + mutate: { + keyDependencies: new Map([[ + newInner, + new Set(['key']) + ]]) + } + } + }, 'observable has the correct mutation dependencies'); + }); +}); +/*can-param@1.1.0#can-param*/ +define('can-param@1.1.0#can-param', [ + 'require', + 'exports', + 'module', + 'can-namespace' +], function (require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + function buildParam(prefix, obj, add) { + if (Array.isArray(obj)) { + for (var i = 0, l = obj.length; i < l; ++i) { + buildParam(prefix + '[]', obj[i], add); + } + } else if (obj && typeof obj === 'object') { + for (var name in obj) { + buildParam(prefix + '[' + name + ']', obj[name], add); + } + } else { + add(prefix, obj); + } + } + module.exports = namespace.param = function param(object) { + var pairs = [], add = function (key, value) { + pairs.push(encodeURIComponent(key) + '=' + encodeURIComponent(value)); + }; + for (var name in object) { + buildParam(name, object[name], add); + } + return pairs.join('&').replace(/%20/g, '+'); + }; +}); +/*can-ajax@2.1.1#can-ajax*/ +define('can-ajax@2.1.1#can-ajax', [ + 'require', + 'exports', + 'module', + 'can-globals/global/global', + 'can-reflect', + 'can-namespace', + 'can-parse-uri', + 'can-param' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var Global = require('can-globals/global/global'); + var canReflect = require('can-reflect'); + var namespace = require('can-namespace'); + var parseURI = require('can-parse-uri'); + var param = require('can-param'); + var xhrs = [ + function () { + return new XMLHttpRequest(); + }, + function () { + return new ActiveXObject('Microsoft.XMLHTTP'); + }, + function () { + return new ActiveXObject('MSXML2.XMLHTTP.3.0'); + }, + function () { + return new ActiveXObject('MSXML2.XMLHTTP'); + } + ], _xhrf = null; + var originUrl = parseURI(Global().location.href); + var globalSettings = {}; + var makeXhr = function () { + if (_xhrf != null) { + return _xhrf(); + } + for (var i = 0, l = xhrs.length; i < l; i++) { + try { + var f = xhrs[i], req = f(); + if (req != null) { + _xhrf = f; + return req; + } + } catch (e) { + continue; + } + } + return function () { + }; + }; + var contentTypes = { + json: 'application/json', + form: 'application/x-www-form-urlencoded' + }; + var _xhrResp = function (xhr, options) { + try { + var type = options.dataType || xhr.getResponseHeader('Content-Type').split(';')[0]; + if (type && (xhr.responseText || xhr.responseXML)) { + switch (type) { + case 'text/xml': + case 'xml': + return xhr.responseXML; + case 'text/json': + case 'application/json': + case 'text/javascript': + case 'application/javascript': + case 'application/x-javascript': + case 'json': + return xhr.responseText && JSON.parse(xhr.responseText); + default: + return xhr.responseText; + } + } else { + return xhr; + } + } catch (e) { + return xhr; + } + }; + function ajax(o) { + var xhr = makeXhr(), timer, n = 0; + var deferred = {}, isFormData; + var promise = new Promise(function (resolve, reject) { + deferred.resolve = resolve; + deferred.reject = reject; + }); + var requestUrl; + promise.abort = function () { + xhr.abort(); + }; + o = [ + { + userAgent: 'XMLHttpRequest', + lang: 'en', + type: 'GET', + data: null, + dataType: 'json' + }, + globalSettings, + o + ].reduce(function (a, b, i) { + return canReflect.assignDeep(a, b); + }); + if (!o.contentType) { + o.contentType = o.type.toUpperCase() === 'GET' ? contentTypes.form : contentTypes.json; + } + if (o.crossDomain == null) { + try { + requestUrl = parseURI(o.url); + o.crossDomain = !!(requestUrl.protocol && requestUrl.protocol !== originUrl.protocol || requestUrl.host && requestUrl.host !== originUrl.host); + } catch (e) { + o.crossDomain = true; + } + } + if (o.timeout) { + timer = setTimeout(function () { + xhr.abort(); + if (o.timeoutFn) { + o.timeoutFn(o.url); + } + }, o.timeout); + } + xhr.onreadystatechange = function () { + try { + if (xhr.readyState === 4) { + if (timer) { + clearTimeout(timer); + } + if (xhr.status < 300) { + if (o.success) { + o.success(_xhrResp(xhr, o)); + } + } else if (o.error) { + o.error(xhr, xhr.status, xhr.statusText); + } + if (o.complete) { + o.complete(xhr, xhr.statusText); + } + if (xhr.status >= 200 && xhr.status < 300) { + deferred.resolve(_xhrResp(xhr, o)); + } else { + deferred.reject(_xhrResp(xhr, o)); + } + } else if (o.progress) { + o.progress(++n); + } + } catch (e) { + deferred.reject(e); + } + }; + var url = o.url, data = null, type = o.type.toUpperCase(); + var isJsonContentType = o.contentType === contentTypes.json; + var isPost = type === 'POST' || type === 'PUT'; + if (!isPost && o.data) { + url += '?' + (isJsonContentType ? JSON.stringify(o.data) : param(o.data)); + } + xhr.open(type, url); + var isSimpleCors = o.crossDomain && [ + 'GET', + 'POST', + 'HEAD' + ].indexOf(type) !== -1; + isFormData = typeof FormData !== 'undefined' && o.data instanceof FormData; + if (isPost) { + if (isFormData) { + data = o.data; + } else { + data = isJsonContentType && !isSimpleCors ? typeof o.data === 'object' ? JSON.stringify(o.data) : o.data : param(o.data); + } + var setContentType = isJsonContentType && !isSimpleCors ? 'application/json' : 'application/x-www-form-urlencoded'; + xhr.setRequestHeader('Content-Type', setContentType); + } else { + xhr.setRequestHeader('Content-Type', o.contentType); + } + if (!isSimpleCors) { + xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); + } + if (o.beforeSend) { + o.beforeSend.call(o, xhr, o); + } + if (o.xhrFields) { + for (var f in o.xhrFields) { + xhr[f] = o.xhrFields[f]; + } + } + xhr.send(data); + return promise; + } + module.exports = namespace.ajax = ajax; + module.exports.ajaxSetup = function (o) { + globalSettings = o || {}; + }; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-make-map@1.2.0#can-make-map*/ +define('can-make-map@1.2.0#can-make-map', function (require, exports, module) { + 'use strict'; + function makeMap(str) { + var obj = {}, items = str.split(','); + items.forEach(function (name) { + obj[name] = true; + }); + return obj; + } + module.exports = makeMap; +}); +/*qunitjs@2.4.1#qunit/qunit*/ +(function (global$1) { + 'use strict'; + global$1 = 'default' in global$1 ? global$1['default'] : global$1; + var window = global$1.window; + var self$1 = global$1.self; + var console = global$1.console; + var setTimeout = global$1.setTimeout; + var clearTimeout = global$1.clearTimeout; + var document = window && window.document; + var navigator = window && window.navigator; + var localSessionStorage = function () { + var x = 'qunit-test-string'; + try { + global$1.sessionStorage.setItem(x, x); + global$1.sessionStorage.removeItem(x); + return global$1.sessionStorage; + } catch (e) { + return undefined; + } + }(); + var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function (obj) { + return typeof obj; + } : function (obj) { + return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj; + }; + var classCallCheck = function (instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError('Cannot call a class as a function'); + } + }; + var createClass = function () { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ('value' in descriptor) + descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + return function (Constructor, protoProps, staticProps) { + if (protoProps) + defineProperties(Constructor.prototype, protoProps); + if (staticProps) + defineProperties(Constructor, staticProps); + return Constructor; + }; + }(); + var toConsumableArray = function (arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) + arr2[i] = arr[i]; + return arr2; + } else { + return Array.from(arr); + } + }; + var toString = Object.prototype.toString; + var hasOwn = Object.prototype.hasOwnProperty; + var now = Date.now || function () { + return new Date().getTime(); + }; + var defined = { + document: window && window.document !== undefined, + setTimeout: setTimeout !== undefined + }; + function diff(a, b) { + var i, j, result = a.slice(); + for (i = 0; i < result.length; i++) { + for (j = 0; j < b.length; j++) { + if (result[i] === b[j]) { + result.splice(i, 1); + i--; + break; + } + } + } + return result; + } + function inArray(elem, array) { + return array.indexOf(elem) !== -1; + } + function objectValues(obj) { + var key, val, vals = is('array', obj) ? [] : {}; + for (key in obj) { + if (hasOwn.call(obj, key)) { + val = obj[key]; + vals[key] = val === Object(val) ? objectValues(val) : val; + } + } + return vals; + } + function extend(a, b, undefOnly) { + for (var prop in b) { + if (hasOwn.call(b, prop)) { + if (b[prop] === undefined) { + delete a[prop]; + } else if (!(undefOnly && typeof a[prop] !== 'undefined')) { + a[prop] = b[prop]; + } + } + } + return a; + } + function objectType(obj) { + if (typeof obj === 'undefined') { + return 'undefined'; + } + if (obj === null) { + return 'null'; + } + var match = toString.call(obj).match(/^\[object\s(.*)\]$/), type = match && match[1]; + switch (type) { + case 'Number': + if (isNaN(obj)) { + return 'nan'; + } + return 'number'; + case 'String': + case 'Boolean': + case 'Array': + case 'Set': + case 'Map': + case 'Date': + case 'RegExp': + case 'Function': + case 'Symbol': + return type.toLowerCase(); + default: + return typeof obj === 'undefined' ? 'undefined' : _typeof(obj); + } + } + function is(type, obj) { + return objectType(obj) === type; + } + function generateHash(module, testName) { + var str = module + '\x1C' + testName; + var hash = 0; + for (var i = 0; i < str.length; i++) { + hash = (hash << 5) - hash + str.charCodeAt(i); + hash |= 0; + } + var hex = (4294967296 + hash).toString(16); + if (hex.length < 8) { + hex = '0000000' + hex; + } + return hex.slice(-8); + } + var equiv = function () { + var pairs = []; + var getProto = Object.getPrototypeOf || function (obj) { + return obj.__proto__; + }; + function useStrictEquality(a, b) { + if ((typeof a === 'undefined' ? 'undefined' : _typeof(a)) === 'object') { + a = a.valueOf(); + } + if ((typeof b === 'undefined' ? 'undefined' : _typeof(b)) === 'object') { + b = b.valueOf(); + } + return a === b; + } + function compareConstructors(a, b) { + var protoA = getProto(a); + var protoB = getProto(b); + if (a.constructor === b.constructor) { + return true; + } + if (protoA && protoA.constructor === null) { + protoA = null; + } + if (protoB && protoB.constructor === null) { + protoB = null; + } + if (protoA === null && protoB === Object.prototype || protoB === null && protoA === Object.prototype) { + return true; + } + return false; + } + function getRegExpFlags(regexp) { + return 'flags' in regexp ? regexp.flags : regexp.toString().match(/[gimuy]*$/)[0]; + } + function isContainer(val) { + return [ + 'object', + 'array', + 'map', + 'set' + ].indexOf(objectType(val)) !== -1; + } + function breadthFirstCompareChild(a, b) { + if (a === b) { + return true; + } + if (!isContainer(a)) { + return typeEquiv(a, b); + } + if (pairs.every(function (pair) { + return pair.a !== a || pair.b !== b; + })) { + pairs.push({ + a: a, + b: b + }); + } + return true; + } + var callbacks = { + 'string': useStrictEquality, + 'boolean': useStrictEquality, + 'number': useStrictEquality, + 'null': useStrictEquality, + 'undefined': useStrictEquality, + 'symbol': useStrictEquality, + 'date': useStrictEquality, + 'nan': function nan() { + return true; + }, + 'regexp': function regexp(a, b) { + return a.source === b.source && getRegExpFlags(a) === getRegExpFlags(b); + }, + 'function': function _function() { + return false; + }, + 'array': function array(a, b) { + var i, len; + len = a.length; + if (len !== b.length) { + return false; + } + for (i = 0; i < len; i++) { + if (!breadthFirstCompareChild(a[i], b[i])) { + return false; + } + } + return true; + }, + 'set': function set$$1(a, b) { + var innerEq, outerEq = true; + if (a.size !== b.size) { + return false; + } + a.forEach(function (aVal) { + if (!outerEq) { + return; + } + innerEq = false; + b.forEach(function (bVal) { + var parentPairs; + if (innerEq) { + return; + } + parentPairs = pairs; + if (innerEquiv(bVal, aVal)) { + innerEq = true; + } + pairs = parentPairs; + }); + if (!innerEq) { + outerEq = false; + } + }); + return outerEq; + }, + 'map': function map(a, b) { + var innerEq, outerEq = true; + if (a.size !== b.size) { + return false; + } + a.forEach(function (aVal, aKey) { + if (!outerEq) { + return; + } + innerEq = false; + b.forEach(function (bVal, bKey) { + var parentPairs; + if (innerEq) { + return; + } + parentPairs = pairs; + if (innerEquiv([ + bVal, + bKey + ], [ + aVal, + aKey + ])) { + innerEq = true; + } + pairs = parentPairs; + }); + if (!innerEq) { + outerEq = false; + } + }); + return outerEq; + }, + 'object': function object(a, b) { + var i, aProperties = [], bProperties = []; + if (compareConstructors(a, b) === false) { + return false; + } + for (i in a) { + aProperties.push(i); + if (a.constructor !== Object && typeof a.constructor !== 'undefined' && typeof a[i] === 'function' && typeof b[i] === 'function' && a[i].toString() === b[i].toString()) { + continue; + } + if (!breadthFirstCompareChild(a[i], b[i])) { + return false; + } + } + for (i in b) { + bProperties.push(i); + } + return typeEquiv(aProperties.sort(), bProperties.sort()); + } + }; + function typeEquiv(a, b) { + var type = objectType(a); + return objectType(b) === type && callbacks[type](a, b); + } + function innerEquiv(a, b) { + var i, pair; + if (arguments.length < 2) { + return true; + } + pairs = [{ + a: a, + b: b + }]; + for (i = 0; i < pairs.length; i++) { + pair = pairs[i]; + if (pair.a !== pair.b && !typeEquiv(pair.a, pair.b)) { + return false; + } + } + return arguments.length === 2 || innerEquiv.apply(this, [].slice.call(arguments, 1)); + } + return function () { + var result = innerEquiv.apply(undefined, arguments); + pairs.length = 0; + return result; + }; + }(); + var config = { + queue: [], + blocking: true, + reorder: true, + altertitle: true, + collapse: true, + scrolltop: true, + maxDepth: 5, + requireExpects: false, + urlConfig: [], + modules: [], + currentModule: { + name: '', + tests: [], + childModules: [], + testsRun: 0, + unskippedTestsRun: 0, + hooks: { + before: [], + beforeEach: [], + afterEach: [], + after: [] + } + }, + callbacks: {}, + storage: localSessionStorage + }; + var globalConfig = window && window.QUnit && window.QUnit.config; + if (window && window.QUnit && !window.QUnit.version) { + extend(config, globalConfig); + } + config.modules.push(config.currentModule); + var dump = function () { + function quote(str) { + return '"' + str.toString().replace(/\\/g, '\\\\').replace(/"/g, '\\"') + '"'; + } + function literal(o) { + return o + ''; + } + function join(pre, arr, post) { + var s = dump.separator(), base = dump.indent(), inner = dump.indent(1); + if (arr.join) { + arr = arr.join(',' + s + inner); + } + if (!arr) { + return pre + post; + } + return [ + pre, + inner + arr, + base + post + ].join(s); + } + function array(arr, stack) { + var i = arr.length, ret = new Array(i); + if (dump.maxDepth && dump.depth > dump.maxDepth) { + return '[object Array]'; + } + this.up(); + while (i--) { + ret[i] = this.parse(arr[i], undefined, stack); + } + this.down(); + return join('[', ret, ']'); + } + function isArray(obj) { + return toString.call(obj) === '[object Array]' || typeof obj.length === 'number' && obj.item !== undefined && (obj.length ? obj.item(0) === obj[0] : obj.item(0) === null && obj[0] === undefined); + } + var reName = /^function (\w+)/, dump = { + parse: function parse(obj, objType, stack) { + stack = stack || []; + var res, parser, parserType, objIndex = stack.indexOf(obj); + if (objIndex !== -1) { + return 'recursion(' + (objIndex - stack.length) + ')'; + } + objType = objType || this.typeOf(obj); + parser = this.parsers[objType]; + parserType = typeof parser === 'undefined' ? 'undefined' : _typeof(parser); + if (parserType === 'function') { + stack.push(obj); + res = parser.call(this, obj, stack); + stack.pop(); + return res; + } + return parserType === 'string' ? parser : this.parsers.error; + }, + typeOf: function typeOf(obj) { + var type; + if (obj === null) { + type = 'null'; + } else if (typeof obj === 'undefined') { + type = 'undefined'; + } else if (is('regexp', obj)) { + type = 'regexp'; + } else if (is('date', obj)) { + type = 'date'; + } else if (is('function', obj)) { + type = 'function'; + } else if (obj.setInterval !== undefined && obj.document !== undefined && obj.nodeType === undefined) { + type = 'window'; + } else if (obj.nodeType === 9) { + type = 'document'; + } else if (obj.nodeType) { + type = 'node'; + } else if (isArray(obj)) { + type = 'array'; + } else if (obj.constructor === Error.prototype.constructor) { + type = 'error'; + } else { + type = typeof obj === 'undefined' ? 'undefined' : _typeof(obj); + } + return type; + }, + separator: function separator() { + if (this.multiline) { + return this.HTML ? '
    ' : '\n'; + } else { + return this.HTML ? ' ' : ' '; + } + }, + indent: function indent(extra) { + if (!this.multiline) { + return ''; + } + var chr = this.indentChar; + if (this.HTML) { + chr = chr.replace(/\t/g, ' ').replace(/ /g, ' '); + } + return new Array(this.depth + (extra || 0)).join(chr); + }, + up: function up(a) { + this.depth += a || 1; + }, + down: function down(a) { + this.depth -= a || 1; + }, + setParser: function setParser(name, parser) { + this.parsers[name] = parser; + }, + quote: quote, + literal: literal, + join: join, + depth: 1, + maxDepth: config.maxDepth, + parsers: { + window: '[Window]', + document: '[Document]', + error: function error(_error) { + return 'Error("' + _error.message + '")'; + }, + unknown: '[Unknown]', + 'null': 'null', + 'undefined': 'undefined', + 'function': function _function(fn) { + var ret = 'function', name = 'name' in fn ? fn.name : (reName.exec(fn) || [])[1]; + if (name) { + ret += ' ' + name; + } + ret += '('; + ret = [ + ret, + dump.parse(fn, 'functionArgs'), + '){' + ].join(''); + return join(ret, dump.parse(fn, 'functionCode'), '}'); + }, + array: array, + nodelist: array, + 'arguments': array, + object: function object(map, stack) { + var keys, key, val, i, nonEnumerableProperties, ret = []; + if (dump.maxDepth && dump.depth > dump.maxDepth) { + return '[object Object]'; + } + dump.up(); + keys = []; + for (key in map) { + keys.push(key); + } + nonEnumerableProperties = [ + 'message', + 'name' + ]; + for (i in nonEnumerableProperties) { + key = nonEnumerableProperties[i]; + if (key in map && !inArray(key, keys)) { + keys.push(key); + } + } + keys.sort(); + for (i = 0; i < keys.length; i++) { + key = keys[i]; + val = map[key]; + ret.push(dump.parse(key, 'key') + ': ' + dump.parse(val, undefined, stack)); + } + dump.down(); + return join('{', ret, '}'); + }, + node: function node(_node) { + var len, i, val, open = dump.HTML ? '<' : '<', close = dump.HTML ? '>' : '>', tag = _node.nodeName.toLowerCase(), ret = open + tag, attrs = _node.attributes; + if (attrs) { + for (i = 0, len = attrs.length; i < len; i++) { + val = attrs[i].nodeValue; + if (val && val !== 'inherit') { + ret += ' ' + attrs[i].nodeName + '=' + dump.parse(val, 'attribute'); + } + } + } + ret += close; + if (_node.nodeType === 3 || _node.nodeType === 4) { + ret += _node.nodeValue; + } + return ret + open + '/' + tag + close; + }, + functionArgs: function functionArgs(fn) { + var args, l = fn.length; + if (!l) { + return ''; + } + args = new Array(l); + while (l--) { + args[l] = String.fromCharCode(97 + l); + } + return ' ' + args.join(', ') + ' '; + }, + key: quote, + functionCode: '[code]', + attribute: quote, + string: quote, + date: quote, + regexp: literal, + number: literal, + 'boolean': literal, + symbol: function symbol(sym) { + return sym.toString(); + } + }, + HTML: false, + indentChar: ' ', + multiline: true + }; + return dump; + }(); + var LISTENERS = Object.create(null); + var SUPPORTED_EVENTS = [ + 'runStart', + 'suiteStart', + 'testStart', + 'assertion', + 'testEnd', + 'suiteEnd', + 'runEnd' + ]; + function emit(eventName, data) { + if (objectType(eventName) !== 'string') { + throw new TypeError('eventName must be a string when emitting an event'); + } + var originalCallbacks = LISTENERS[eventName]; + var callbacks = originalCallbacks ? [].concat(toConsumableArray(originalCallbacks)) : []; + for (var i = 0; i < callbacks.length; i++) { + callbacks[i](data); + } + } + function on(eventName, callback) { + if (objectType(eventName) !== 'string') { + throw new TypeError('eventName must be a string when registering a listener'); + } else if (!inArray(eventName, SUPPORTED_EVENTS)) { + var events = SUPPORTED_EVENTS.join(', '); + throw new Error('"' + eventName + '" is not a valid event; must be one of: ' + events + '.'); + } else if (objectType(callback) !== 'function') { + throw new TypeError('callback must be a function when registering a listener'); + } + if (!LISTENERS[eventName]) { + LISTENERS[eventName] = []; + } + if (!inArray(callback, LISTENERS[eventName])) { + LISTENERS[eventName].push(callback); + } + } + function registerLoggingCallbacks(obj) { + var i, l, key, callbackNames = [ + 'begin', + 'done', + 'log', + 'testStart', + 'testDone', + 'moduleStart', + 'moduleDone' + ]; + function registerLoggingCallback(key) { + var loggingCallback = function loggingCallback(callback) { + if (objectType(callback) !== 'function') { + throw new Error('QUnit logging methods require a callback function as their first parameters.'); + } + config.callbacks[key].push(callback); + }; + return loggingCallback; + } + for (i = 0, l = callbackNames.length; i < l; i++) { + key = callbackNames[i]; + if (objectType(config.callbacks[key]) === 'undefined') { + config.callbacks[key] = []; + } + obj[key] = registerLoggingCallback(key); + } + } + function runLoggingCallbacks(key, args) { + var i, l, callbacks; + callbacks = config.callbacks[key]; + for (i = 0, l = callbacks.length; i < l; i++) { + callbacks[i](args); + } + } + var fileName = (sourceFromStacktrace(0) || '').replace(/(:\d+)+\)?/, '').replace(/.+\//, ''); + function extractStacktrace(e, offset) { + offset = offset === undefined ? 4 : offset; + var stack, include, i; + if (e && e.stack) { + stack = e.stack.split('\n'); + if (/^error$/i.test(stack[0])) { + stack.shift(); + } + if (fileName) { + include = []; + for (i = offset; i < stack.length; i++) { + if (stack[i].indexOf(fileName) !== -1) { + break; + } + include.push(stack[i]); + } + if (include.length) { + return include.join('\n'); + } + } + return stack[offset]; + } + } + function sourceFromStacktrace(offset) { + var error = new Error(); + if (!error.stack) { + try { + throw error; + } catch (err) { + error = err; + } + } + return extractStacktrace(error, offset); + } + var priorityCount = 0; + var unitSampler = void 0; + function advance() { + var start = now(); + config.depth = (config.depth || 0) + 1; + while (config.queue.length && !config.blocking) { + var elapsedTime = now() - start; + if (!defined.setTimeout || config.updateRate <= 0 || elapsedTime < config.updateRate) { + if (priorityCount > 0) { + priorityCount--; + } + config.queue.shift()(); + } else { + setTimeout(advance, 13); + break; + } + } + config.depth--; + if (!config.blocking && !config.queue.length && config.depth === 0) { + done(); + } + } + function addToQueueImmediate(callback) { + if (objectType(callback) === 'array') { + while (callback.length) { + addToQueueImmediate(callback.pop()); + } + return; + } + config.queue.unshift(callback); + priorityCount++; + } + function addToQueue(callback, prioritize, seed) { + if (prioritize) { + config.queue.splice(priorityCount++, 0, callback); + } else if (seed) { + if (!unitSampler) { + unitSampler = unitSamplerGenerator(seed); + } + var index = Math.floor(unitSampler() * (config.queue.length - priorityCount + 1)); + config.queue.splice(priorityCount + index, 0, callback); + } else { + config.queue.push(callback); + } + } + function unitSamplerGenerator(seed) { + var sample = parseInt(generateHash(seed), 16) || -1; + return function () { + sample ^= sample << 13; + sample ^= sample >>> 17; + sample ^= sample << 5; + if (sample < 0) { + sample += 4294967296; + } + return sample / 4294967296; + }; + } + function done() { + var storage = config.storage; + ProcessingQueue.finished = true; + var runtime = now() - config.started; + var passed = config.stats.all - config.stats.bad; + emit('runEnd', globalSuite.end(true)); + runLoggingCallbacks('done', { + passed: passed, + failed: config.stats.bad, + total: config.stats.all, + runtime: runtime + }); + if (storage && config.stats.bad === 0) { + for (var i = storage.length - 1; i >= 0; i--) { + var key = storage.key(i); + if (key.indexOf('qunit-test-') === 0) { + storage.removeItem(key); + } + } + } + } + var ProcessingQueue = { + finished: false, + add: addToQueue, + addImmediate: addToQueueImmediate, + advance: advance + }; + var TestReport = function () { + function TestReport(name, suite, options) { + classCallCheck(this, TestReport); + this.name = name; + this.suiteName = suite.name; + this.fullName = suite.fullName.concat(name); + this.runtime = 0; + this.assertions = []; + this.skipped = !!options.skip; + this.todo = !!options.todo; + this.valid = options.valid; + this._startTime = 0; + this._endTime = 0; + suite.pushTest(this); + } + createClass(TestReport, [ + { + key: 'start', + value: function start(recordTime) { + if (recordTime) { + this._startTime = Date.now(); + } + return { + name: this.name, + suiteName: this.suiteName, + fullName: this.fullName.slice() + }; + } + }, + { + key: 'end', + value: function end(recordTime) { + if (recordTime) { + this._endTime = Date.now(); + } + return extend(this.start(), { + runtime: this.getRuntime(), + status: this.getStatus(), + errors: this.getFailedAssertions(), + assertions: this.getAssertions() + }); + } + }, + { + key: 'pushAssertion', + value: function pushAssertion(assertion) { + this.assertions.push(assertion); + } + }, + { + key: 'getRuntime', + value: function getRuntime() { + return this._endTime - this._startTime; + } + }, + { + key: 'getStatus', + value: function getStatus() { + if (this.skipped) { + return 'skipped'; + } + var testPassed = this.getFailedAssertions().length > 0 ? this.todo : !this.todo; + if (!testPassed) { + return 'failed'; + } else if (this.todo) { + return 'todo'; + } else { + return 'passed'; + } + } + }, + { + key: 'getFailedAssertions', + value: function getFailedAssertions() { + return this.assertions.filter(function (assertion) { + return !assertion.passed; + }); + } + }, + { + key: 'getAssertions', + value: function getAssertions() { + return this.assertions.slice(); + } + }, + { + key: 'slimAssertions', + value: function slimAssertions() { + this.assertions = this.assertions.map(function (assertion) { + delete assertion.actual; + delete assertion.expected; + return assertion; + }); + } + } + ]); + return TestReport; + }(); + var focused$1 = false; + function Test(settings) { + var i, l; + ++Test.count; + this.expected = null; + this.assertions = []; + this.semaphore = 0; + this.module = config.currentModule; + this.stack = sourceFromStacktrace(3); + this.steps = []; + this.timeout = undefined; + if (this.module.skip) { + settings.skip = true; + settings.todo = false; + } else if (this.module.todo && !settings.skip) { + settings.todo = true; + } + extend(this, settings); + this.testReport = new TestReport(settings.testName, this.module.suiteReport, { + todo: settings.todo, + skip: settings.skip, + valid: this.valid() + }); + for (i = 0, l = this.module.tests; i < l.length; i++) { + if (this.module.tests[i].name === this.testName) { + this.testName += ' '; + } + } + this.testId = generateHash(this.module.name, this.testName); + this.module.tests.push({ + name: this.testName, + testId: this.testId, + skip: !!settings.skip + }); + if (settings.skip) { + this.callback = function () { + }; + this.async = false; + this.expected = 0; + } else { + if (typeof this.callback !== 'function') { + var method = this.todo ? 'todo' : 'test'; + throw new TypeError('You must provide a function as a test callback to QUnit.' + method + '("' + settings.testName + '")'); + } + this.assert = new Assert(this); + } + } + Test.count = 0; + function getNotStartedModules(startModule) { + var module = startModule, modules = []; + while (module && module.testsRun === 0) { + modules.push(module); + module = module.parentModule; + } + return modules; + } + Test.prototype = { + before: function before() { + var i, startModule, module = this.module, notStartedModules = getNotStartedModules(module); + for (i = notStartedModules.length - 1; i >= 0; i--) { + startModule = notStartedModules[i]; + startModule.stats = { + all: 0, + bad: 0, + started: now() + }; + emit('suiteStart', startModule.suiteReport.start(true)); + runLoggingCallbacks('moduleStart', { + name: startModule.name, + tests: startModule.tests + }); + } + config.current = this; + this.testEnvironment = extend({}, module.testEnvironment); + this.started = now(); + emit('testStart', this.testReport.start(true)); + runLoggingCallbacks('testStart', { + name: this.testName, + module: module.name, + testId: this.testId, + previousFailure: this.previousFailure + }); + if (!config.pollution) { + saveGlobal(); + } + }, + run: function run() { + var promise; + config.current = this; + this.callbackStarted = now(); + if (config.notrycatch) { + runTest(this); + return; + } + try { + runTest(this); + } catch (e) { + this.pushFailure('Died on test #' + (this.assertions.length + 1) + ' ' + this.stack + ': ' + (e.message || e), extractStacktrace(e, 0)); + saveGlobal(); + if (config.blocking) { + internalRecover(this); + } + } + function runTest(test) { + promise = test.callback.call(test.testEnvironment, test.assert); + test.resolvePromise(promise); + if (test.timeout === 0 && test.semaphore !== 0) { + pushFailure('Test did not finish synchronously even though assert.timeout( 0 ) was used.', sourceFromStacktrace(2)); + } + } + }, + after: function after() { + checkPollution(); + }, + queueHook: function queueHook(hook, hookName, hookOwner) { + var _this = this; + var callHook = function callHook() { + var promise = hook.call(_this.testEnvironment, _this.assert); + _this.resolvePromise(promise, hookName); + }; + var runHook = function runHook() { + if (hookName === 'before') { + if (hookOwner.unskippedTestsRun !== 0) { + return; + } + _this.preserveEnvironment = true; + } + if (hookName === 'after' && hookOwner.unskippedTestsRun !== numberOfUnskippedTests(hookOwner) - 1 && config.queue.length > 2) { + return; + } + config.current = _this; + if (config.notrycatch) { + callHook(); + return; + } + try { + callHook(); + } catch (error) { + _this.pushFailure(hookName + ' failed on ' + _this.testName + ': ' + (error.message || error), extractStacktrace(error, 0)); + } + }; + return runHook; + }, + hooks: function hooks(handler) { + var hooks = []; + function processHooks(test, module) { + if (module.parentModule) { + processHooks(test, module.parentModule); + } + if (module.hooks[handler].length) { + for (var i = 0; i < module.hooks[handler].length; i++) { + hooks.push(test.queueHook(module.hooks[handler][i], handler, module)); + } + } + } + if (!this.skip) { + processHooks(this, this.module); + } + return hooks; + }, + finish: function finish() { + config.current = this; + if (config.requireExpects && this.expected === null) { + this.pushFailure('Expected number of assertions to be defined, but expect() was ' + 'not called.', this.stack); + } else if (this.expected !== null && this.expected !== this.assertions.length) { + this.pushFailure('Expected ' + this.expected + ' assertions, but ' + this.assertions.length + ' were run', this.stack); + } else if (this.expected === null && !this.assertions.length) { + this.pushFailure('Expected at least one assertion, but none were run - call ' + 'expect(0) to accept zero assertions.', this.stack); + } + var i, module = this.module, moduleName = module.name, testName = this.testName, skipped = !!this.skip, todo = !!this.todo, bad = 0, storage = config.storage; + this.runtime = now() - this.started; + config.stats.all += this.assertions.length; + module.stats.all += this.assertions.length; + for (i = 0; i < this.assertions.length; i++) { + if (!this.assertions[i].result) { + bad++; + config.stats.bad++; + module.stats.bad++; + } + } + notifyTestsRan(module, skipped); + if (storage) { + if (bad) { + storage.setItem('qunit-test-' + moduleName + '-' + testName, bad); + } else { + storage.removeItem('qunit-test-' + moduleName + '-' + testName); + } + } + emit('testEnd', this.testReport.end(true)); + this.testReport.slimAssertions(); + runLoggingCallbacks('testDone', { + name: testName, + module: moduleName, + skipped: skipped, + todo: todo, + failed: bad, + passed: this.assertions.length - bad, + total: this.assertions.length, + runtime: skipped ? 0 : this.runtime, + assertions: this.assertions, + testId: this.testId, + source: this.stack + }); + if (module.testsRun === numberOfTests(module)) { + logSuiteEnd(module); + var parent = module.parentModule; + while (parent && parent.testsRun === numberOfTests(parent)) { + logSuiteEnd(parent); + parent = parent.parentModule; + } + } + config.current = undefined; + function logSuiteEnd(module) { + emit('suiteEnd', module.suiteReport.end(true)); + runLoggingCallbacks('moduleDone', { + name: module.name, + tests: module.tests, + failed: module.stats.bad, + passed: module.stats.all - module.stats.bad, + total: module.stats.all, + runtime: now() - module.stats.started + }); + } + }, + preserveTestEnvironment: function preserveTestEnvironment() { + if (this.preserveEnvironment) { + this.module.testEnvironment = this.testEnvironment; + this.testEnvironment = extend({}, this.module.testEnvironment); + } + }, + queue: function queue() { + var test = this; + if (!this.valid()) { + return; + } + function runTest() { + ProcessingQueue.addImmediate([ + function () { + test.before(); + }, + test.hooks('before'), + function () { + test.preserveTestEnvironment(); + }, + test.hooks('beforeEach'), + function () { + test.run(); + }, + test.hooks('afterEach').reverse(), + test.hooks('after').reverse(), + function () { + test.after(); + }, + function () { + test.finish(); + } + ]); + } + var previousFailCount = config.storage && +config.storage.getItem('qunit-test-' + this.module.name + '-' + this.testName); + var prioritize = config.reorder && !!previousFailCount; + this.previousFailure = !!previousFailCount; + ProcessingQueue.add(runTest, prioritize, config.seed); + if (ProcessingQueue.finished) { + ProcessingQueue.advance(); + } + }, + pushResult: function pushResult(resultInfo) { + if (this !== config.current) { + throw new Error('Assertion occured after test had finished.'); + } + var source, details = { + module: this.module.name, + name: this.testName, + result: resultInfo.result, + message: resultInfo.message, + actual: resultInfo.actual, + testId: this.testId, + negative: resultInfo.negative || false, + runtime: now() - this.started, + todo: !!this.todo + }; + if (hasOwn.call(resultInfo, 'expected')) { + details.expected = resultInfo.expected; + } + if (!resultInfo.result) { + source = resultInfo.source || sourceFromStacktrace(); + if (source) { + details.source = source; + } + } + this.logAssertion(details); + this.assertions.push({ + result: !!resultInfo.result, + message: resultInfo.message + }); + }, + pushFailure: function pushFailure(message, source, actual) { + if (!(this instanceof Test)) { + throw new Error('pushFailure() assertion outside test context, was ' + sourceFromStacktrace(2)); + } + this.pushResult({ + result: false, + message: message || 'error', + actual: actual || null, + source: source + }); + }, + logAssertion: function logAssertion(details) { + runLoggingCallbacks('log', details); + var assertion = { + passed: details.result, + actual: details.actual, + expected: details.expected, + message: details.message, + stack: details.source, + todo: details.todo + }; + this.testReport.pushAssertion(assertion); + emit('assertion', assertion); + }, + resolvePromise: function resolvePromise(promise, phase) { + var then, resume, message, test = this; + if (promise != null) { + then = promise.then; + if (objectType(then) === 'function') { + resume = internalStop(test); + then.call(promise, function () { + resume(); + }, function (error) { + message = 'Promise rejected ' + (!phase ? 'during' : phase.replace(/Each$/, '')) + ' "' + test.testName + '": ' + (error && error.message || error); + test.pushFailure(message, extractStacktrace(error, 0)); + saveGlobal(); + resume(); + }); + } + } + }, + valid: function valid() { + var filter = config.filter, regexFilter = /^(!?)\/([\w\W]*)\/(i?$)/.exec(filter), module = config.module && config.module.toLowerCase(), fullName = this.module.name + ': ' + this.testName; + function moduleChainNameMatch(testModule) { + var testModuleName = testModule.name ? testModule.name.toLowerCase() : null; + if (testModuleName === module) { + return true; + } else if (testModule.parentModule) { + return moduleChainNameMatch(testModule.parentModule); + } else { + return false; + } + } + function moduleChainIdMatch(testModule) { + return inArray(testModule.moduleId, config.moduleId) || testModule.parentModule && moduleChainIdMatch(testModule.parentModule); + } + if (this.callback && this.callback.validTest) { + return true; + } + if (config.moduleId && config.moduleId.length > 0 && !moduleChainIdMatch(this.module)) { + return false; + } + if (config.testId && config.testId.length > 0 && !inArray(this.testId, config.testId)) { + return false; + } + if (module && !moduleChainNameMatch(this.module)) { + return false; + } + if (!filter) { + return true; + } + return regexFilter ? this.regexFilter(!!regexFilter[1], regexFilter[2], regexFilter[3], fullName) : this.stringFilter(filter, fullName); + }, + regexFilter: function regexFilter(exclude, pattern, flags, fullName) { + var regex = new RegExp(pattern, flags); + var match = regex.test(fullName); + return match !== exclude; + }, + stringFilter: function stringFilter(filter, fullName) { + filter = filter.toLowerCase(); + fullName = fullName.toLowerCase(); + var include = filter.charAt(0) !== '!'; + if (!include) { + filter = filter.slice(1); + } + if (fullName.indexOf(filter) !== -1) { + return include; + } + return !include; + } + }; + function pushFailure() { + if (!config.current) { + throw new Error('pushFailure() assertion outside test context, in ' + sourceFromStacktrace(2)); + } + var currentTest = config.current; + return currentTest.pushFailure.apply(currentTest, arguments); + } + function saveGlobal() { + config.pollution = []; + if (config.noglobals) { + for (var key in global$1) { + if (hasOwn.call(global$1, key)) { + if (/^qunit-test-output/.test(key)) { + continue; + } + config.pollution.push(key); + } + } + } + } + function checkPollution() { + var newGlobals, deletedGlobals, old = config.pollution; + saveGlobal(); + newGlobals = diff(config.pollution, old); + if (newGlobals.length > 0) { + pushFailure('Introduced global variable(s): ' + newGlobals.join(', ')); + } + deletedGlobals = diff(old, config.pollution); + if (deletedGlobals.length > 0) { + pushFailure('Deleted global variable(s): ' + deletedGlobals.join(', ')); + } + } + function test(testName, callback) { + if (focused$1) { + return; + } + var newTest = new Test({ + testName: testName, + callback: callback + }); + newTest.queue(); + } + function todo(testName, callback) { + if (focused$1) { + return; + } + var newTest = new Test({ + testName: testName, + callback: callback, + todo: true + }); + newTest.queue(); + } + function skip(testName) { + if (focused$1) { + return; + } + var test = new Test({ + testName: testName, + skip: true + }); + test.queue(); + } + function only(testName, callback) { + if (focused$1) { + return; + } + config.queue.length = 0; + focused$1 = true; + var newTest = new Test({ + testName: testName, + callback: callback + }); + newTest.queue(); + } + function internalStop(test) { + test.semaphore += 1; + config.blocking = true; + if (defined.setTimeout) { + var timeoutDuration = void 0; + if (typeof test.timeout === 'number') { + timeoutDuration = test.timeout; + } else if (typeof config.testTimeout === 'number') { + timeoutDuration = config.testTimeout; + } + if (typeof timeoutDuration === 'number' && timeoutDuration > 0) { + clearTimeout(config.timeout); + config.timeout = setTimeout(function () { + pushFailure('Test took longer than ' + timeoutDuration + 'ms; test timed out.', sourceFromStacktrace(2)); + internalRecover(test); + }, timeoutDuration); + } + } + var released = false; + return function resume() { + if (released) { + return; + } + released = true; + test.semaphore -= 1; + internalStart(test); + }; + } + function internalRecover(test) { + test.semaphore = 0; + internalStart(test); + } + function internalStart(test) { + if (isNaN(test.semaphore)) { + test.semaphore = 0; + pushFailure('Invalid value on test.semaphore', sourceFromStacktrace(2)); + return; + } + if (test.semaphore > 0) { + return; + } + if (test.semaphore < 0) { + test.semaphore = 0; + pushFailure('Tried to restart test while already started (test\'s semaphore was 0 already)', sourceFromStacktrace(2)); + return; + } + if (defined.setTimeout) { + if (config.timeout) { + clearTimeout(config.timeout); + } + config.timeout = setTimeout(function () { + if (test.semaphore > 0) { + return; + } + if (config.timeout) { + clearTimeout(config.timeout); + } + begin(); + }, 13); + } else { + begin(); + } + } + function collectTests(module) { + var tests = [].concat(module.tests); + var modules = [].concat(toConsumableArray(module.childModules)); + while (modules.length) { + var nextModule = modules.shift(); + tests.push.apply(tests, nextModule.tests); + modules.push.apply(modules, toConsumableArray(nextModule.childModules)); + } + return tests; + } + function numberOfTests(module) { + return collectTests(module).length; + } + function numberOfUnskippedTests(module) { + return collectTests(module).filter(function (test) { + return !test.skip; + }).length; + } + function notifyTestsRan(module, skipped) { + module.testsRun++; + if (!skipped) { + module.unskippedTestsRun++; + } + while (module = module.parentModule) { + module.testsRun++; + if (!skipped) { + module.unskippedTestsRun++; + } + } + } + function consoleProxy(method) { + return function () { + if (console) { + console[method].apply(console, arguments); + } + }; + } + var Logger = { warn: consoleProxy('warn') }; + var Assert = function () { + function Assert(testContext) { + classCallCheck(this, Assert); + this.test = testContext; + } + createClass(Assert, [ + { + key: 'timeout', + value: function timeout(duration) { + if (typeof duration !== 'number') { + throw new Error('You must pass a number as the duration to assert.timeout'); + } + this.test.timeout = duration; + } + }, + { + key: 'step', + value: function step(message) { + var result = !!message; + this.test.steps.push(message); + return this.pushResult({ + result: result, + message: message || 'You must provide a message to assert.step' + }); + } + }, + { + key: 'verifySteps', + value: function verifySteps(steps, message) { + this.deepEqual(this.test.steps, steps, message); + } + }, + { + key: 'expect', + value: function expect(asserts) { + if (arguments.length === 1) { + this.test.expected = asserts; + } else { + return this.test.expected; + } + } + }, + { + key: 'async', + value: function async(count) { + var test$$1 = this.test; + var popped = false, acceptCallCount = count; + if (typeof acceptCallCount === 'undefined') { + acceptCallCount = 1; + } + var resume = internalStop(test$$1); + return function done() { + if (config.current !== test$$1) { + throw Error('assert.async callback called after test finished.'); + } + if (popped) { + test$$1.pushFailure('Too many calls to the `assert.async` callback', sourceFromStacktrace(2)); + return; + } + acceptCallCount -= 1; + if (acceptCallCount > 0) { + return; + } + popped = true; + resume(); + }; + } + }, + { + key: 'push', + value: function push(result, actual, expected, message, negative) { + Logger.warn('assert.push is deprecated and will be removed in QUnit 3.0.' + ' Please use assert.pushResult instead (https://api.qunitjs.com/assert/pushResult).'); + var currentAssert = this instanceof Assert ? this : config.current.assert; + return currentAssert.pushResult({ + result: result, + actual: actual, + expected: expected, + message: message, + negative: negative + }); + } + }, + { + key: 'pushResult', + value: function pushResult(resultInfo) { + var assert = this; + var currentTest = assert instanceof Assert && assert.test || config.current; + if (!currentTest) { + throw new Error('assertion outside test context, in ' + sourceFromStacktrace(2)); + } + if (!(assert instanceof Assert)) { + assert = currentTest.assert; + } + return assert.test.pushResult(resultInfo); + } + }, + { + key: 'ok', + value: function ok(result, message) { + if (!message) { + message = result ? 'okay' : 'failed, expected argument to be truthy, was: ' + dump.parse(result); + } + this.pushResult({ + result: !!result, + actual: result, + expected: true, + message: message + }); + } + }, + { + key: 'notOk', + value: function notOk(result, message) { + if (!message) { + message = !result ? 'okay' : 'failed, expected argument to be falsy, was: ' + dump.parse(result); + } + this.pushResult({ + result: !result, + actual: result, + expected: false, + message: message + }); + } + }, + { + key: 'equal', + value: function equal(actual, expected, message) { + var result = expected == actual; + this.pushResult({ + result: result, + actual: actual, + expected: expected, + message: message + }); + } + }, + { + key: 'notEqual', + value: function notEqual(actual, expected, message) { + var result = expected != actual; + this.pushResult({ + result: result, + actual: actual, + expected: expected, + message: message, + negative: true + }); + } + }, + { + key: 'propEqual', + value: function propEqual(actual, expected, message) { + actual = objectValues(actual); + expected = objectValues(expected); + this.pushResult({ + result: equiv(actual, expected), + actual: actual, + expected: expected, + message: message + }); + } + }, + { + key: 'notPropEqual', + value: function notPropEqual(actual, expected, message) { + actual = objectValues(actual); + expected = objectValues(expected); + this.pushResult({ + result: !equiv(actual, expected), + actual: actual, + expected: expected, + message: message, + negative: true + }); + } + }, + { + key: 'deepEqual', + value: function deepEqual(actual, expected, message) { + this.pushResult({ + result: equiv(actual, expected), + actual: actual, + expected: expected, + message: message + }); + } + }, + { + key: 'notDeepEqual', + value: function notDeepEqual(actual, expected, message) { + this.pushResult({ + result: !equiv(actual, expected), + actual: actual, + expected: expected, + message: message, + negative: true + }); + } + }, + { + key: 'strictEqual', + value: function strictEqual(actual, expected, message) { + this.pushResult({ + result: expected === actual, + actual: actual, + expected: expected, + message: message + }); + } + }, + { + key: 'notStrictEqual', + value: function notStrictEqual(actual, expected, message) { + this.pushResult({ + result: expected !== actual, + actual: actual, + expected: expected, + message: message, + negative: true + }); + } + }, + { + key: 'throws', + value: function throws(block, expected, message) { + var actual = void 0, result = false; + var currentTest = this instanceof Assert && this.test || config.current; + if (objectType(expected) === 'string') { + if (message == null) { + message = expected; + expected = null; + } else { + throw new Error('throws/raises does not accept a string value for the expected argument.\n' + 'Use a non-string object value (e.g. regExp) instead if it\'s necessary.'); + } + } + currentTest.ignoreGlobalErrors = true; + try { + block.call(currentTest.testEnvironment); + } catch (e) { + actual = e; + } + currentTest.ignoreGlobalErrors = false; + if (actual) { + var expectedType = objectType(expected); + if (!expected) { + result = true; + expected = null; + } else if (expectedType === 'regexp') { + result = expected.test(errorString(actual)); + } else if (expectedType === 'function' && actual instanceof expected) { + result = true; + } else if (expectedType === 'object') { + result = actual instanceof expected.constructor && actual.name === expected.name && actual.message === expected.message; + } else if (expectedType === 'function' && expected.call({}, actual) === true) { + expected = null; + result = true; + } + } + currentTest.assert.pushResult({ + result: result, + actual: actual, + expected: expected, + message: message + }); + } + } + ]); + return Assert; + }(); + Assert.prototype.raises = Assert.prototype['throws']; + function errorString(error) { + var resultErrorString = error.toString(); + if (resultErrorString.substring(0, 7) === '[object') { + var name = error.name ? error.name.toString() : 'Error'; + var message = error.message ? error.message.toString() : ''; + if (name && message) { + return name + ': ' + message; + } else if (name) { + return name; + } else if (message) { + return message; + } else { + return 'Error'; + } + } else { + return resultErrorString; + } + } + function exportQUnit(QUnit) { + if (defined.document) { + if (window.QUnit && window.QUnit.version) { + throw new Error('QUnit has already been defined.'); + } + window.QUnit = QUnit; + } + if (typeof module !== 'undefined' && module && module.exports) { + module.exports = QUnit; + module.exports.QUnit = QUnit; + } + if (typeof exports !== 'undefined' && exports) { + exports.QUnit = QUnit; + } + if (typeof define === 'function' && define.amd) { + define('qunitjs@2.4.1#qunit/qunit', function () { + return QUnit; + }); + QUnit.config.autostart = false; + } + if (self$1 && self$1.WorkerGlobalScope && self$1 instanceof self$1.WorkerGlobalScope) { + self$1.QUnit = QUnit; + } + } + var SuiteReport = function () { + function SuiteReport(name, parentSuite) { + classCallCheck(this, SuiteReport); + this.name = name; + this.fullName = parentSuite ? parentSuite.fullName.concat(name) : []; + this.tests = []; + this.childSuites = []; + if (parentSuite) { + parentSuite.pushChildSuite(this); + } + } + createClass(SuiteReport, [ + { + key: 'start', + value: function start(recordTime) { + if (recordTime) { + this._startTime = Date.now(); + } + return { + name: this.name, + fullName: this.fullName.slice(), + tests: this.tests.map(function (test) { + return test.start(); + }), + childSuites: this.childSuites.map(function (suite) { + return suite.start(); + }), + testCounts: { total: this.getTestCounts().total } + }; + } + }, + { + key: 'end', + value: function end(recordTime) { + if (recordTime) { + this._endTime = Date.now(); + } + return { + name: this.name, + fullName: this.fullName.slice(), + tests: this.tests.map(function (test) { + return test.end(); + }), + childSuites: this.childSuites.map(function (suite) { + return suite.end(); + }), + testCounts: this.getTestCounts(), + runtime: this.getRuntime(), + status: this.getStatus() + }; + } + }, + { + key: 'pushChildSuite', + value: function pushChildSuite(suite) { + this.childSuites.push(suite); + } + }, + { + key: 'pushTest', + value: function pushTest(test) { + this.tests.push(test); + } + }, + { + key: 'getRuntime', + value: function getRuntime() { + return this._endTime - this._startTime; + } + }, + { + key: 'getTestCounts', + value: function getTestCounts() { + var counts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { + passed: 0, + failed: 0, + skipped: 0, + todo: 0, + total: 0 + }; + counts = this.tests.reduce(function (counts, test) { + if (test.valid) { + counts[test.getStatus()]++; + counts.total++; + } + return counts; + }, counts); + return this.childSuites.reduce(function (counts, suite) { + return suite.getTestCounts(counts); + }, counts); + } + }, + { + key: 'getStatus', + value: function getStatus() { + var _getTestCounts = this.getTestCounts(), total = _getTestCounts.total, failed = _getTestCounts.failed, skipped = _getTestCounts.skipped, todo = _getTestCounts.todo; + if (failed) { + return 'failed'; + } else { + if (skipped === total) { + return 'skipped'; + } else if (todo === total) { + return 'todo'; + } else { + return 'passed'; + } + } + } + } + ]); + return SuiteReport; + }(); + function onError(error) { + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + if (config.current) { + if (config.current.ignoreGlobalErrors) { + return true; + } + pushFailure.apply(undefined, [ + error.message, + error.fileName + ':' + error.lineNumber + ].concat(args)); + } else { + test('global failure', extend(function () { + pushFailure.apply(undefined, [ + error.message, + error.fileName + ':' + error.lineNumber + ].concat(args)); + }, { validTest: true })); + } + return false; + } + var focused = false; + var QUnit = {}; + var globalSuite = new SuiteReport(); + config.currentModule.suiteReport = globalSuite; + var moduleStack = []; + var globalStartCalled = false; + var runStarted = false; + QUnit.isLocal = !(defined.document && window.location.protocol !== 'file:'); + QUnit.version = '2.4.1'; + function createModule(name, testEnvironment, modifiers) { + var parentModule = moduleStack.length ? moduleStack.slice(-1)[0] : null; + var moduleName = parentModule !== null ? [ + parentModule.name, + name + ].join(' > ') : name; + var parentSuite = parentModule ? parentModule.suiteReport : globalSuite; + var skip$$1 = parentModule !== null && parentModule.skip || modifiers.skip; + var todo$$1 = parentModule !== null && parentModule.todo || modifiers.todo; + var module = { + name: moduleName, + parentModule: parentModule, + tests: [], + moduleId: generateHash(moduleName), + testsRun: 0, + unskippedTestsRun: 0, + childModules: [], + suiteReport: new SuiteReport(name, parentSuite), + skip: skip$$1, + todo: skip$$1 ? false : todo$$1 + }; + var env = {}; + if (parentModule) { + parentModule.childModules.push(module); + extend(env, parentModule.testEnvironment); + } + extend(env, testEnvironment); + module.testEnvironment = env; + config.modules.push(module); + return module; + } + function processModule(name, options, executeNow) { + var modifiers = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + var module = createModule(name, options, modifiers); + var testEnvironment = module.testEnvironment; + var hooks = module.hooks = {}; + setHookFromEnvironment(hooks, testEnvironment, 'before'); + setHookFromEnvironment(hooks, testEnvironment, 'beforeEach'); + setHookFromEnvironment(hooks, testEnvironment, 'afterEach'); + setHookFromEnvironment(hooks, testEnvironment, 'after'); + function setHookFromEnvironment(hooks, environment, name) { + var potentialHook = environment[name]; + hooks[name] = typeof potentialHook === 'function' ? [potentialHook] : []; + delete environment[name]; + } + var moduleFns = { + before: setHookFunction(module, 'before'), + beforeEach: setHookFunction(module, 'beforeEach'), + afterEach: setHookFunction(module, 'afterEach'), + after: setHookFunction(module, 'after') + }; + var currentModule = config.currentModule; + if (objectType(executeNow) === 'function') { + moduleStack.push(module); + config.currentModule = module; + executeNow.call(module.testEnvironment, moduleFns); + moduleStack.pop(); + module = module.parentModule || currentModule; + } + config.currentModule = module; + } + function module$1(name, options, executeNow) { + if (focused) { + return; + } + if (arguments.length === 2) { + if (objectType(options) === 'function') { + executeNow = options; + options = undefined; + } + } + processModule(name, options, executeNow); + } + module$1.only = function () { + if (focused) { + return; + } + config.modules.length = 0; + config.queue.length = 0; + module$1.apply(undefined, arguments); + focused = true; + }; + module$1.skip = function (name, options, executeNow) { + if (focused) { + return; + } + if (arguments.length === 2) { + if (objectType(options) === 'function') { + executeNow = options; + options = undefined; + } + } + processModule(name, options, executeNow, { skip: true }); + }; + module$1.todo = function (name, options, executeNow) { + if (focused) { + return; + } + if (arguments.length === 2) { + if (objectType(options) === 'function') { + executeNow = options; + options = undefined; + } + } + processModule(name, options, executeNow, { todo: true }); + }; + extend(QUnit, { + on: on, + module: module$1, + test: test, + todo: todo, + skip: skip, + only: only, + start: function start(count) { + var globalStartAlreadyCalled = globalStartCalled; + if (!config.current) { + globalStartCalled = true; + if (runStarted) { + throw new Error('Called start() while test already started running'); + } else if (globalStartAlreadyCalled || count > 1) { + throw new Error('Called start() outside of a test context too many times'); + } else if (config.autostart) { + throw new Error('Called start() outside of a test context when ' + 'QUnit.config.autostart was true'); + } else if (!config.pageLoaded) { + config.autostart = true; + if (!defined.document) { + QUnit.load(); + } + return; + } + } else { + throw new Error('QUnit.start cannot be called inside a test context.'); + } + scheduleBegin(); + }, + config: config, + is: is, + objectType: objectType, + extend: extend, + load: function load() { + config.pageLoaded = true; + extend(config, { + stats: { + all: 0, + bad: 0 + }, + started: 0, + updateRate: 1000, + autostart: true, + filter: '' + }, true); + if (!runStarted) { + config.blocking = false; + if (config.autostart) { + scheduleBegin(); + } + } + }, + stack: function stack(offset) { + offset = (offset || 0) + 2; + return sourceFromStacktrace(offset); + }, + onError: onError + }); + QUnit.pushFailure = pushFailure; + QUnit.assert = Assert.prototype; + QUnit.equiv = equiv; + QUnit.dump = dump; + registerLoggingCallbacks(QUnit); + function scheduleBegin() { + runStarted = true; + if (defined.setTimeout) { + setTimeout(function () { + begin(); + }, 13); + } else { + begin(); + } + } + function begin() { + var i, l, modulesLog = []; + if (!config.started) { + config.started = now(); + if (config.modules[0].name === '' && config.modules[0].tests.length === 0) { + config.modules.shift(); + } + for (i = 0, l = config.modules.length; i < l; i++) { + modulesLog.push({ + name: config.modules[i].name, + tests: config.modules[i].tests + }); + } + emit('runStart', globalSuite.start(true)); + runLoggingCallbacks('begin', { + totalTests: Test.count, + modules: modulesLog + }); + } + config.blocking = false; + ProcessingQueue.advance(); + } + function setHookFunction(module, hookName) { + return function setHook(callback) { + module.hooks[hookName].push(callback); + }; + } + exportQUnit(QUnit); + (function () { + if (typeof window === 'undefined' || typeof document === 'undefined') { + return; + } + var config = QUnit.config, hasOwn = Object.prototype.hasOwnProperty; + function storeFixture() { + if (hasOwn.call(config, 'fixture')) { + return; + } + var fixture = document.getElementById('qunit-fixture'); + if (fixture) { + config.fixture = fixture.innerHTML; + } + } + QUnit.begin(storeFixture); + function resetFixture() { + if (config.fixture == null) { + return; + } + var fixture = document.getElementById('qunit-fixture'); + if (fixture) { + fixture.innerHTML = config.fixture; + } + } + QUnit.testStart(resetFixture); + }()); + (function () { + var location = typeof window !== 'undefined' && window.location; + if (!location) { + return; + } + var urlParams = getUrlParams(); + QUnit.urlParams = urlParams; + QUnit.config.moduleId = [].concat(urlParams.moduleId || []); + QUnit.config.testId = [].concat(urlParams.testId || []); + QUnit.config.module = urlParams.module; + QUnit.config.filter = urlParams.filter; + if (urlParams.seed === true) { + QUnit.config.seed = Math.random().toString(36).slice(2); + } else if (urlParams.seed) { + QUnit.config.seed = urlParams.seed; + } + QUnit.config.urlConfig.push({ + id: 'hidepassed', + label: 'Hide passed tests', + tooltip: 'Only show tests and assertions that fail. Stored as query-strings.' + }, { + id: 'noglobals', + label: 'Check for Globals', + tooltip: 'Enabling this will test if any test introduces new properties on the ' + 'global object (`window` in Browsers). Stored as query-strings.' + }, { + id: 'notrycatch', + label: 'No try-catch', + tooltip: 'Enabling this will run tests outside of a try-catch block. Makes debugging ' + 'exceptions in IE reasonable. Stored as query-strings.' + }); + QUnit.begin(function () { + var i, option, urlConfig = QUnit.config.urlConfig; + for (i = 0; i < urlConfig.length; i++) { + option = QUnit.config.urlConfig[i]; + if (typeof option !== 'string') { + option = option.id; + } + if (QUnit.config[option] === undefined) { + QUnit.config[option] = urlParams[option]; + } + } + }); + function getUrlParams() { + var i, param, name, value; + var urlParams = Object.create(null); + var params = location.search.slice(1).split('&'); + var length = params.length; + for (i = 0; i < length; i++) { + if (params[i]) { + param = params[i].split('='); + name = decodeQueryParam(param[0]); + value = param.length === 1 || decodeQueryParam(param.slice(1).join('=')); + if (name in urlParams) { + urlParams[name] = [].concat(urlParams[name], value); + } else { + urlParams[name] = value; + } + } + } + return urlParams; + } + function decodeQueryParam(param) { + return decodeURIComponent(param.replace(/\+/g, '%20')); + } + }()); + var stats = { + passedTests: 0, + failedTests: 0, + skippedTests: 0, + todoTests: 0 + }; + function escapeText(s) { + if (!s) { + return ''; + } + s = s + ''; + return s.replace(/['"<>&]/g, function (s) { + switch (s) { + case '\'': + return '''; + case '"': + return '"'; + case '<': + return '<'; + case '>': + return '>'; + case '&': + return '&'; + } + }); + } + (function () { + if (typeof window === 'undefined' || !window.document) { + return; + } + var config = QUnit.config, document$$1 = window.document, collapseNext = false, hasOwn = Object.prototype.hasOwnProperty, unfilteredUrl = setUrl({ + filter: undefined, + module: undefined, + moduleId: undefined, + testId: undefined + }), modulesList = []; + function addEvent(elem, type, fn) { + elem.addEventListener(type, fn, false); + } + function removeEvent(elem, type, fn) { + elem.removeEventListener(type, fn, false); + } + function addEvents(elems, type, fn) { + var i = elems.length; + while (i--) { + addEvent(elems[i], type, fn); + } + } + function hasClass(elem, name) { + return (' ' + elem.className + ' ').indexOf(' ' + name + ' ') >= 0; + } + function addClass(elem, name) { + if (!hasClass(elem, name)) { + elem.className += (elem.className ? ' ' : '') + name; + } + } + function toggleClass(elem, name, force) { + if (force || typeof force === 'undefined' && !hasClass(elem, name)) { + addClass(elem, name); + } else { + removeClass(elem, name); + } + } + function removeClass(elem, name) { + var set = ' ' + elem.className + ' '; + while (set.indexOf(' ' + name + ' ') >= 0) { + set = set.replace(' ' + name + ' ', ' '); + } + elem.className = typeof set.trim === 'function' ? set.trim() : set.replace(/^\s+|\s+$/g, ''); + } + function id(name) { + return document$$1.getElementById && document$$1.getElementById(name); + } + function abortTests() { + var abortButton = id('qunit-abort-tests-button'); + if (abortButton) { + abortButton.disabled = true; + abortButton.innerHTML = 'Aborting...'; + } + QUnit.config.queue.length = 0; + return false; + } + function interceptNavigation(ev) { + applyUrlParams(); + if (ev && ev.preventDefault) { + ev.preventDefault(); + } + return false; + } + function getUrlConfigHtml() { + var i, j, val, escaped, escapedTooltip, selection = false, urlConfig = config.urlConfig, urlConfigHtml = ''; + for (i = 0; i < urlConfig.length; i++) { + val = config.urlConfig[i]; + if (typeof val === 'string') { + val = { + id: val, + label: val + }; + } + escaped = escapeText(val.id); + escapedTooltip = escapeText(val.tooltip); + if (!val.value || typeof val.value === 'string') { + urlConfigHtml += ''; + } else { + urlConfigHtml += ''; + } + } + return urlConfigHtml; + } + function toolbarChanged() { + var updatedUrl, value, tests, field = this, params = {}; + if ('selectedIndex' in field) { + value = field.options[field.selectedIndex].value || undefined; + } else { + value = field.checked ? field.defaultValue || true : undefined; + } + params[field.name] = value; + updatedUrl = setUrl(params); + if ('hidepassed' === field.name && 'replaceState' in window.history) { + QUnit.urlParams[field.name] = value; + config[field.name] = value || false; + tests = id('qunit-tests'); + if (tests) { + toggleClass(tests, 'hidepass', value || false); + } + window.history.replaceState(null, '', updatedUrl); + } else { + window.location = updatedUrl; + } + } + function setUrl(params) { + var key, arrValue, i, querystring = '?', location = window.location; + params = QUnit.extend(QUnit.extend({}, QUnit.urlParams), params); + for (key in params) { + if (hasOwn.call(params, key) && params[key] !== undefined) { + arrValue = [].concat(params[key]); + for (i = 0; i < arrValue.length; i++) { + querystring += encodeURIComponent(key); + if (arrValue[i] !== true) { + querystring += '=' + encodeURIComponent(arrValue[i]); + } + querystring += '&'; + } + } + } + return location.protocol + '//' + location.host + location.pathname + querystring.slice(0, -1); + } + function applyUrlParams() { + var i, selectedModules = [], modulesList = id('qunit-modulefilter-dropdown-list').getElementsByTagName('input'), filter = id('qunit-filter-input').value; + for (i = 0; i < modulesList.length; i++) { + if (modulesList[i].checked) { + selectedModules.push(modulesList[i].value); + } + } + window.location = setUrl({ + filter: filter === '' ? undefined : filter, + moduleId: selectedModules.length === 0 ? undefined : selectedModules, + module: undefined, + testId: undefined + }); + } + function toolbarUrlConfigContainer() { + var urlConfigContainer = document$$1.createElement('span'); + urlConfigContainer.innerHTML = getUrlConfigHtml(); + addClass(urlConfigContainer, 'qunit-url-config'); + addEvents(urlConfigContainer.getElementsByTagName('input'), 'change', toolbarChanged); + addEvents(urlConfigContainer.getElementsByTagName('select'), 'change', toolbarChanged); + return urlConfigContainer; + } + function abortTestsButton() { + var button = document$$1.createElement('button'); + button.id = 'qunit-abort-tests-button'; + button.innerHTML = 'Abort'; + addEvent(button, 'click', abortTests); + return button; + } + function toolbarLooseFilter() { + var filter = document$$1.createElement('form'), label = document$$1.createElement('label'), input = document$$1.createElement('input'), button = document$$1.createElement('button'); + addClass(filter, 'qunit-filter'); + label.innerHTML = 'Filter: '; + input.type = 'text'; + input.value = config.filter || ''; + input.name = 'filter'; + input.id = 'qunit-filter-input'; + button.innerHTML = 'Go'; + label.appendChild(input); + filter.appendChild(label); + filter.appendChild(document$$1.createTextNode(' ')); + filter.appendChild(button); + addEvent(filter, 'submit', interceptNavigation); + return filter; + } + function moduleListHtml() { + var i, checked, html = ''; + for (i = 0; i < config.modules.length; i++) { + if (config.modules[i].name !== '') { + checked = config.moduleId.indexOf(config.modules[i].moduleId) > -1; + html += '
  3. '; + } + } + return html; + } + function toolbarModuleFilter() { + var allCheckbox, commit, reset, moduleFilter = document$$1.createElement('form'), label = document$$1.createElement('label'), moduleSearch = document$$1.createElement('input'), dropDown = document$$1.createElement('div'), actions = document$$1.createElement('span'), dropDownList = document$$1.createElement('ul'), dirty = false; + moduleSearch.id = 'qunit-modulefilter-search'; + addEvent(moduleSearch, 'input', searchInput); + addEvent(moduleSearch, 'input', searchFocus); + addEvent(moduleSearch, 'focus', searchFocus); + addEvent(moduleSearch, 'click', searchFocus); + label.id = 'qunit-modulefilter-search-container'; + label.innerHTML = 'Module: '; + label.appendChild(moduleSearch); + actions.id = 'qunit-modulefilter-actions'; + actions.innerHTML = '' + '' + ''; + allCheckbox = actions.lastChild.firstChild; + commit = actions.firstChild; + reset = commit.nextSibling; + addEvent(commit, 'click', applyUrlParams); + dropDownList.id = 'qunit-modulefilter-dropdown-list'; + dropDownList.innerHTML = moduleListHtml(); + dropDown.id = 'qunit-modulefilter-dropdown'; + dropDown.style.display = 'none'; + dropDown.appendChild(actions); + dropDown.appendChild(dropDownList); + addEvent(dropDown, 'change', selectionChange); + selectionChange(); + moduleFilter.id = 'qunit-modulefilter'; + moduleFilter.appendChild(label); + moduleFilter.appendChild(dropDown); + addEvent(moduleFilter, 'submit', interceptNavigation); + addEvent(moduleFilter, 'reset', function () { + window.setTimeout(selectionChange); + }); + function searchFocus() { + if (dropDown.style.display !== 'none') { + return; + } + dropDown.style.display = 'block'; + addEvent(document$$1, 'click', hideHandler); + addEvent(document$$1, 'keydown', hideHandler); + function hideHandler(e) { + var inContainer = moduleFilter.contains(e.target); + if (e.keyCode === 27 || !inContainer) { + if (e.keyCode === 27 && inContainer) { + moduleSearch.focus(); + } + dropDown.style.display = 'none'; + removeEvent(document$$1, 'click', hideHandler); + removeEvent(document$$1, 'keydown', hideHandler); + moduleSearch.value = ''; + searchInput(); + } + } + } + function searchInput() { + var i, item, searchText = moduleSearch.value.toLowerCase(), listItems = dropDownList.children; + for (i = 0; i < listItems.length; i++) { + item = listItems[i]; + if (!searchText || item.textContent.toLowerCase().indexOf(searchText) > -1) { + item.style.display = ''; + } else { + item.style.display = 'none'; + } + } + } + function selectionChange(evt) { + var i, item, checkbox = evt && evt.target || allCheckbox, modulesList = dropDownList.getElementsByTagName('input'), selectedNames = []; + toggleClass(checkbox.parentNode, 'checked', checkbox.checked); + dirty = false; + if (checkbox.checked && checkbox !== allCheckbox) { + allCheckbox.checked = false; + removeClass(allCheckbox.parentNode, 'checked'); + } + for (i = 0; i < modulesList.length; i++) { + item = modulesList[i]; + if (!evt) { + toggleClass(item.parentNode, 'checked', item.checked); + } else if (checkbox === allCheckbox && checkbox.checked) { + item.checked = false; + removeClass(item.parentNode, 'checked'); + } + dirty = dirty || item.checked !== item.defaultChecked; + if (item.checked) { + selectedNames.push(item.parentNode.textContent); + } + } + commit.style.display = reset.style.display = dirty ? '' : 'none'; + moduleSearch.placeholder = selectedNames.join(', ') || allCheckbox.parentNode.textContent; + moduleSearch.title = 'Type to filter list. Current selection:\n' + (selectedNames.join('\n') || allCheckbox.parentNode.textContent); + } + return moduleFilter; + } + function appendToolbar() { + var toolbar = id('qunit-testrunner-toolbar'); + if (toolbar) { + toolbar.appendChild(toolbarUrlConfigContainer()); + toolbar.appendChild(toolbarModuleFilter()); + toolbar.appendChild(toolbarLooseFilter()); + toolbar.appendChild(document$$1.createElement('div')).className = 'clearfix'; + } + } + function appendHeader() { + var header = id('qunit-header'); + if (header) { + header.innerHTML = '' + header.innerHTML + ' '; + } + } + function appendBanner() { + var banner = id('qunit-banner'); + if (banner) { + banner.className = ''; + } + } + function appendTestResults() { + var tests = id('qunit-tests'), result = id('qunit-testresult'), controls; + if (result) { + result.parentNode.removeChild(result); + } + if (tests) { + tests.innerHTML = ''; + result = document$$1.createElement('p'); + result.id = 'qunit-testresult'; + result.className = 'result'; + tests.parentNode.insertBefore(result, tests); + result.innerHTML = '
    Running...
     
    ' + '
    ' + '
    '; + controls = id('qunit-testresult-controls'); + } + if (controls) { + controls.appendChild(abortTestsButton()); + } + } + function appendFilteredTest() { + var testId = QUnit.config.testId; + if (!testId || testId.length <= 0) { + return ''; + } + return '
    Rerunning selected tests: ' + escapeText(testId.join(', ')) + ' Run all tests
    '; + } + function appendUserAgent() { + var userAgent = id('qunit-userAgent'); + if (userAgent) { + userAgent.innerHTML = ''; + userAgent.appendChild(document$$1.createTextNode('QUnit ' + QUnit.version + '; ' + navigator.userAgent)); + } + } + function appendInterface() { + var qunit = id('qunit'); + if (qunit) { + qunit.innerHTML = '

    ' + escapeText(document$$1.title) + '

    ' + '

    ' + '
    ' + appendFilteredTest() + '

    ' + '
      '; + } + appendHeader(); + appendBanner(); + appendTestResults(); + appendUserAgent(); + appendToolbar(); + } + function appendTestsList(modules) { + var i, l, x, z, test, moduleObj; + for (i = 0, l = modules.length; i < l; i++) { + moduleObj = modules[i]; + for (x = 0, z = moduleObj.tests.length; x < z; x++) { + test = moduleObj.tests[x]; + appendTest(test.name, test.testId, moduleObj.name); + } + } + } + function appendTest(name, testId, moduleName) { + var title, rerunTrigger, testBlock, assertList, tests = id('qunit-tests'); + if (!tests) { + return; + } + title = document$$1.createElement('strong'); + title.innerHTML = getNameHtml(name, moduleName); + rerunTrigger = document$$1.createElement('a'); + rerunTrigger.innerHTML = 'Rerun'; + rerunTrigger.href = setUrl({ testId: testId }); + testBlock = document$$1.createElement('li'); + testBlock.appendChild(title); + testBlock.appendChild(rerunTrigger); + testBlock.id = 'qunit-test-output-' + testId; + assertList = document$$1.createElement('ol'); + assertList.className = 'qunit-assert-list'; + testBlock.appendChild(assertList); + tests.appendChild(testBlock); + } + QUnit.begin(function (details) { + var i, moduleObj, tests; + for (i = 0; i < details.modules.length; i++) { + moduleObj = details.modules[i]; + if (moduleObj.name) { + modulesList.push(moduleObj.name); + } + } + modulesList.sort(function (a, b) { + return a.localeCompare(b); + }); + appendInterface(); + appendTestsList(details.modules); + tests = id('qunit-tests'); + if (tests && config.hidepassed) { + addClass(tests, 'hidepass'); + } + }); + QUnit.done(function (details) { + var banner = id('qunit-banner'), tests = id('qunit-tests'), abortButton = id('qunit-abort-tests-button'), totalTests = stats.passedTests + stats.skippedTests + stats.todoTests + stats.failedTests, html = [ + totalTests, + ' tests completed in ', + details.runtime, + ' milliseconds, with ', + stats.failedTests, + ' failed, ', + stats.skippedTests, + ' skipped, and ', + stats.todoTests, + ' todo.
      ', + '', + details.passed, + ' assertions of ', + details.total, + ' passed, ', + details.failed, + ' failed.' + ].join(''), test, assertLi, assertList; + if (abortButton && abortButton.disabled) { + html = 'Tests aborted after ' + details.runtime + ' milliseconds.'; + for (var i = 0; i < tests.children.length; i++) { + test = tests.children[i]; + if (test.className === '' || test.className === 'running') { + test.className = 'aborted'; + assertList = test.getElementsByTagName('ol')[0]; + assertLi = document$$1.createElement('li'); + assertLi.className = 'fail'; + assertLi.innerHTML = 'Test aborted.'; + assertList.appendChild(assertLi); + } + } + } + if (banner && (!abortButton || abortButton.disabled === false)) { + banner.className = stats.failedTests ? 'qunit-fail' : 'qunit-pass'; + } + if (abortButton) { + abortButton.parentNode.removeChild(abortButton); + } + if (tests) { + id('qunit-testresult-display').innerHTML = html; + } + if (config.altertitle && document$$1.title) { + document$$1.title = [ + stats.failedTests ? '\u2716' : '\u2714', + document$$1.title.replace(/^[\u2714\u2716] /i, '') + ].join(' '); + } + if (config.scrolltop && window.scrollTo) { + window.scrollTo(0, 0); + } + }); + function getNameHtml(name, module) { + var nameHtml = ''; + if (module) { + nameHtml = '' + escapeText(module) + ': '; + } + nameHtml += '' + escapeText(name) + ''; + return nameHtml; + } + QUnit.testStart(function (details) { + var running, testBlock, bad; + testBlock = id('qunit-test-output-' + details.testId); + if (testBlock) { + testBlock.className = 'running'; + } else { + appendTest(details.name, details.testId, details.module); + } + running = id('qunit-testresult-display'); + if (running) { + bad = QUnit.config.reorder && details.previousFailure; + running.innerHTML = [ + bad ? 'Rerunning previously failed test:
      ' : 'Running:
      ', + getNameHtml(details.name, details.module) + ].join(''); + } + }); + function stripHtml(string) { + return string.replace(/<\/?[^>]+(>|$)/g, '').replace(/\"/g, '').replace(/\s+/g, ''); + } + QUnit.log(function (details) { + var assertList, assertLi, message, expected, actual, diff, showDiff = false, testItem = id('qunit-test-output-' + details.testId); + if (!testItem) { + return; + } + message = escapeText(details.message) || (details.result ? 'okay' : 'failed'); + message = '' + message + ''; + message += '@ ' + details.runtime + ' ms'; + if (!details.result && hasOwn.call(details, 'expected')) { + if (details.negative) { + expected = 'NOT ' + QUnit.dump.parse(details.expected); + } else { + expected = QUnit.dump.parse(details.expected); + } + actual = QUnit.dump.parse(details.actual); + message += ''; + if (actual !== expected) { + message += ''; + if (typeof details.actual === 'number' && typeof details.expected === 'number') { + if (!isNaN(details.actual) && !isNaN(details.expected)) { + showDiff = true; + diff = details.actual - details.expected; + diff = (diff > 0 ? '+' : '') + diff; + } + } else if (typeof details.actual !== 'boolean' && typeof details.expected !== 'boolean') { + diff = QUnit.diff(expected, actual); + showDiff = stripHtml(diff).length !== stripHtml(expected).length + stripHtml(actual).length; + } + if (showDiff) { + message += ''; + } + } else if (expected.indexOf('[object Array]') !== -1 || expected.indexOf('[object Object]') !== -1) { + message += ''; + } else { + message += ''; + } + if (details.source) { + message += ''; + } + message += '
      Expected:
      ' + escapeText(expected) + '
      Result:
      ' + escapeText(actual) + '
      Diff:
      ' + diff + '
      Message: ' + 'Diff suppressed as the depth of object is more than current max depth (' + QUnit.config.maxDepth + ').

      Hint: Use QUnit.dump.maxDepth to ' + ' run with a higher max depth or ' + 'Rerun without max depth.

      Message: ' + 'Diff suppressed as the expected and actual results have an equivalent' + ' serialization
      Source:
      ' + escapeText(details.source) + '
      '; + } else if (!details.result && details.source) { + message += '' + '' + '
      Source:
      ' + escapeText(details.source) + '
      '; + } + assertList = testItem.getElementsByTagName('ol')[0]; + assertLi = document$$1.createElement('li'); + assertLi.className = details.result ? 'pass' : 'fail'; + assertLi.innerHTML = message; + assertList.appendChild(assertLi); + }); + QUnit.testDone(function (details) { + var testTitle, time, testItem, assertList, good, bad, testCounts, skipped, sourceName, tests = id('qunit-tests'); + if (!tests) { + return; + } + testItem = id('qunit-test-output-' + details.testId); + assertList = testItem.getElementsByTagName('ol')[0]; + good = details.passed; + bad = details.failed; + var testPassed = details.failed > 0 ? details.todo : !details.todo; + if (testPassed) { + addClass(assertList, 'qunit-collapsed'); + } else if (config.collapse) { + if (!collapseNext) { + collapseNext = true; + } else { + addClass(assertList, 'qunit-collapsed'); + } + } + testTitle = testItem.firstChild; + testCounts = bad ? '' + bad + ', ' + '' + good + ', ' : ''; + testTitle.innerHTML += ' (' + testCounts + details.assertions.length + ')'; + if (details.skipped) { + stats.skippedTests++; + testItem.className = 'skipped'; + skipped = document$$1.createElement('em'); + skipped.className = 'qunit-skipped-label'; + skipped.innerHTML = 'skipped'; + testItem.insertBefore(skipped, testTitle); + } else { + addEvent(testTitle, 'click', function () { + toggleClass(assertList, 'qunit-collapsed'); + }); + testItem.className = testPassed ? 'pass' : 'fail'; + if (details.todo) { + var todoLabel = document$$1.createElement('em'); + todoLabel.className = 'qunit-todo-label'; + todoLabel.innerHTML = 'todo'; + testItem.className += ' todo'; + testItem.insertBefore(todoLabel, testTitle); + } + time = document$$1.createElement('span'); + time.className = 'runtime'; + time.innerHTML = details.runtime + ' ms'; + testItem.insertBefore(time, assertList); + if (!testPassed) { + stats.failedTests++; + } else if (details.todo) { + stats.todoTests++; + } else { + stats.passedTests++; + } + } + if (details.source) { + sourceName = document$$1.createElement('p'); + sourceName.innerHTML = 'Source: ' + details.source; + addClass(sourceName, 'qunit-source'); + if (testPassed) { + addClass(sourceName, 'qunit-collapsed'); + } + addEvent(testTitle, 'click', function () { + toggleClass(sourceName, 'qunit-collapsed'); + }); + testItem.appendChild(sourceName); + } + }); + var notPhantom = function (p) { + return !(p && p.version && p.version.major > 0); + }(window.phantom); + if (notPhantom && document$$1.readyState === 'complete') { + QUnit.load(); + } else { + addEvent(window, 'load', QUnit.load); + } + var originalWindowOnError = window.onerror; + window.onerror = function (message, fileName, lineNumber) { + var ret = false; + if (originalWindowOnError) { + for (var _len = arguments.length, args = Array(_len > 3 ? _len - 3 : 0), _key = 3; _key < _len; _key++) { + args[_key - 3] = arguments[_key]; + } + ret = originalWindowOnError.call.apply(originalWindowOnError, [ + this, + message, + fileName, + lineNumber + ].concat(args)); + } + if (ret !== true) { + var error = { + message: message, + fileName: fileName, + lineNumber: lineNumber + }; + ret = QUnit.onError(error); + } + return ret; + }; + }()); + QUnit.diff = function () { + function DiffMatchPatch() { + } + var DIFF_DELETE = -1, DIFF_INSERT = 1, DIFF_EQUAL = 0; + DiffMatchPatch.prototype.DiffMain = function (text1, text2, optChecklines) { + var deadline, checklines, commonlength, commonprefix, commonsuffix, diffs; + deadline = new Date().getTime() + 1000; + if (text1 === null || text2 === null) { + throw new Error('Null input. (DiffMain)'); + } + if (text1 === text2) { + if (text1) { + return [[ + DIFF_EQUAL, + text1 + ]]; + } + return []; + } + if (typeof optChecklines === 'undefined') { + optChecklines = true; + } + checklines = optChecklines; + commonlength = this.diffCommonPrefix(text1, text2); + commonprefix = text1.substring(0, commonlength); + text1 = text1.substring(commonlength); + text2 = text2.substring(commonlength); + commonlength = this.diffCommonSuffix(text1, text2); + commonsuffix = text1.substring(text1.length - commonlength); + text1 = text1.substring(0, text1.length - commonlength); + text2 = text2.substring(0, text2.length - commonlength); + diffs = this.diffCompute(text1, text2, checklines, deadline); + if (commonprefix) { + diffs.unshift([ + DIFF_EQUAL, + commonprefix + ]); + } + if (commonsuffix) { + diffs.push([ + DIFF_EQUAL, + commonsuffix + ]); + } + this.diffCleanupMerge(diffs); + return diffs; + }; + DiffMatchPatch.prototype.diffCleanupEfficiency = function (diffs) { + var changes, equalities, equalitiesLength, lastequality, pointer, preIns, preDel, postIns, postDel; + changes = false; + equalities = []; + equalitiesLength = 0; + lastequality = null; + pointer = 0; + preIns = false; + preDel = false; + postIns = false; + postDel = false; + while (pointer < diffs.length) { + if (diffs[pointer][0] === DIFF_EQUAL) { + if (diffs[pointer][1].length < 4 && (postIns || postDel)) { + equalities[equalitiesLength++] = pointer; + preIns = postIns; + preDel = postDel; + lastequality = diffs[pointer][1]; + } else { + equalitiesLength = 0; + lastequality = null; + } + postIns = postDel = false; + } else { + if (diffs[pointer][0] === DIFF_DELETE) { + postDel = true; + } else { + postIns = true; + } + if (lastequality && (preIns && preDel && postIns && postDel || lastequality.length < 2 && preIns + preDel + postIns + postDel === 3)) { + diffs.splice(equalities[equalitiesLength - 1], 0, [ + DIFF_DELETE, + lastequality + ]); + diffs[equalities[equalitiesLength - 1] + 1][0] = DIFF_INSERT; + equalitiesLength--; + lastequality = null; + if (preIns && preDel) { + postIns = postDel = true; + equalitiesLength = 0; + } else { + equalitiesLength--; + pointer = equalitiesLength > 0 ? equalities[equalitiesLength - 1] : -1; + postIns = postDel = false; + } + changes = true; + } + } + pointer++; + } + if (changes) { + this.diffCleanupMerge(diffs); + } + }; + DiffMatchPatch.prototype.diffPrettyHtml = function (diffs) { + var op, data, x, html = []; + for (x = 0; x < diffs.length; x++) { + op = diffs[x][0]; + data = diffs[x][1]; + switch (op) { + case DIFF_INSERT: + html[x] = '' + escapeText(data) + ''; + break; + case DIFF_DELETE: + html[x] = '' + escapeText(data) + ''; + break; + case DIFF_EQUAL: + html[x] = '' + escapeText(data) + ''; + break; + } + } + return html.join(''); + }; + DiffMatchPatch.prototype.diffCommonPrefix = function (text1, text2) { + var pointermid, pointermax, pointermin, pointerstart; + if (!text1 || !text2 || text1.charAt(0) !== text2.charAt(0)) { + return 0; + } + pointermin = 0; + pointermax = Math.min(text1.length, text2.length); + pointermid = pointermax; + pointerstart = 0; + while (pointermin < pointermid) { + if (text1.substring(pointerstart, pointermid) === text2.substring(pointerstart, pointermid)) { + pointermin = pointermid; + pointerstart = pointermin; + } else { + pointermax = pointermid; + } + pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin); + } + return pointermid; + }; + DiffMatchPatch.prototype.diffCommonSuffix = function (text1, text2) { + var pointermid, pointermax, pointermin, pointerend; + if (!text1 || !text2 || text1.charAt(text1.length - 1) !== text2.charAt(text2.length - 1)) { + return 0; + } + pointermin = 0; + pointermax = Math.min(text1.length, text2.length); + pointermid = pointermax; + pointerend = 0; + while (pointermin < pointermid) { + if (text1.substring(text1.length - pointermid, text1.length - pointerend) === text2.substring(text2.length - pointermid, text2.length - pointerend)) { + pointermin = pointermid; + pointerend = pointermin; + } else { + pointermax = pointermid; + } + pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin); + } + return pointermid; + }; + DiffMatchPatch.prototype.diffCompute = function (text1, text2, checklines, deadline) { + var diffs, longtext, shorttext, i, hm, text1A, text2A, text1B, text2B, midCommon, diffsA, diffsB; + if (!text1) { + return [[ + DIFF_INSERT, + text2 + ]]; + } + if (!text2) { + return [[ + DIFF_DELETE, + text1 + ]]; + } + longtext = text1.length > text2.length ? text1 : text2; + shorttext = text1.length > text2.length ? text2 : text1; + i = longtext.indexOf(shorttext); + if (i !== -1) { + diffs = [ + [ + DIFF_INSERT, + longtext.substring(0, i) + ], + [ + DIFF_EQUAL, + shorttext + ], + [ + DIFF_INSERT, + longtext.substring(i + shorttext.length) + ] + ]; + if (text1.length > text2.length) { + diffs[0][0] = diffs[2][0] = DIFF_DELETE; + } + return diffs; + } + if (shorttext.length === 1) { + return [ + [ + DIFF_DELETE, + text1 + ], + [ + DIFF_INSERT, + text2 + ] + ]; + } + hm = this.diffHalfMatch(text1, text2); + if (hm) { + text1A = hm[0]; + text1B = hm[1]; + text2A = hm[2]; + text2B = hm[3]; + midCommon = hm[4]; + diffsA = this.DiffMain(text1A, text2A, checklines, deadline); + diffsB = this.DiffMain(text1B, text2B, checklines, deadline); + return diffsA.concat([[ + DIFF_EQUAL, + midCommon + ]], diffsB); + } + if (checklines && text1.length > 100 && text2.length > 100) { + return this.diffLineMode(text1, text2, deadline); + } + return this.diffBisect(text1, text2, deadline); + }; + DiffMatchPatch.prototype.diffHalfMatch = function (text1, text2) { + var longtext, shorttext, dmp, text1A, text2B, text2A, text1B, midCommon, hm1, hm2, hm; + longtext = text1.length > text2.length ? text1 : text2; + shorttext = text1.length > text2.length ? text2 : text1; + if (longtext.length < 4 || shorttext.length * 2 < longtext.length) { + return null; + } + dmp = this; + function diffHalfMatchI(longtext, shorttext, i) { + var seed, j, bestCommon, prefixLength, suffixLength, bestLongtextA, bestLongtextB, bestShorttextA, bestShorttextB; + seed = longtext.substring(i, i + Math.floor(longtext.length / 4)); + j = -1; + bestCommon = ''; + while ((j = shorttext.indexOf(seed, j + 1)) !== -1) { + prefixLength = dmp.diffCommonPrefix(longtext.substring(i), shorttext.substring(j)); + suffixLength = dmp.diffCommonSuffix(longtext.substring(0, i), shorttext.substring(0, j)); + if (bestCommon.length < suffixLength + prefixLength) { + bestCommon = shorttext.substring(j - suffixLength, j) + shorttext.substring(j, j + prefixLength); + bestLongtextA = longtext.substring(0, i - suffixLength); + bestLongtextB = longtext.substring(i + prefixLength); + bestShorttextA = shorttext.substring(0, j - suffixLength); + bestShorttextB = shorttext.substring(j + prefixLength); + } + } + if (bestCommon.length * 2 >= longtext.length) { + return [ + bestLongtextA, + bestLongtextB, + bestShorttextA, + bestShorttextB, + bestCommon + ]; + } else { + return null; + } + } + hm1 = diffHalfMatchI(longtext, shorttext, Math.ceil(longtext.length / 4)); + hm2 = diffHalfMatchI(longtext, shorttext, Math.ceil(longtext.length / 2)); + if (!hm1 && !hm2) { + return null; + } else if (!hm2) { + hm = hm1; + } else if (!hm1) { + hm = hm2; + } else { + hm = hm1[4].length > hm2[4].length ? hm1 : hm2; + } + if (text1.length > text2.length) { + text1A = hm[0]; + text1B = hm[1]; + text2A = hm[2]; + text2B = hm[3]; + } else { + text2A = hm[0]; + text2B = hm[1]; + text1A = hm[2]; + text1B = hm[3]; + } + midCommon = hm[4]; + return [ + text1A, + text1B, + text2A, + text2B, + midCommon + ]; + }; + DiffMatchPatch.prototype.diffLineMode = function (text1, text2, deadline) { + var a, diffs, linearray, pointer, countInsert, countDelete, textInsert, textDelete, j; + a = this.diffLinesToChars(text1, text2); + text1 = a.chars1; + text2 = a.chars2; + linearray = a.lineArray; + diffs = this.DiffMain(text1, text2, false, deadline); + this.diffCharsToLines(diffs, linearray); + this.diffCleanupSemantic(diffs); + diffs.push([ + DIFF_EQUAL, + '' + ]); + pointer = 0; + countDelete = 0; + countInsert = 0; + textDelete = ''; + textInsert = ''; + while (pointer < diffs.length) { + switch (diffs[pointer][0]) { + case DIFF_INSERT: + countInsert++; + textInsert += diffs[pointer][1]; + break; + case DIFF_DELETE: + countDelete++; + textDelete += diffs[pointer][1]; + break; + case DIFF_EQUAL: + if (countDelete >= 1 && countInsert >= 1) { + diffs.splice(pointer - countDelete - countInsert, countDelete + countInsert); + pointer = pointer - countDelete - countInsert; + a = this.DiffMain(textDelete, textInsert, false, deadline); + for (j = a.length - 1; j >= 0; j--) { + diffs.splice(pointer, 0, a[j]); + } + pointer = pointer + a.length; + } + countInsert = 0; + countDelete = 0; + textDelete = ''; + textInsert = ''; + break; + } + pointer++; + } + diffs.pop(); + return diffs; + }; + DiffMatchPatch.prototype.diffBisect = function (text1, text2, deadline) { + var text1Length, text2Length, maxD, vOffset, vLength, v1, v2, x, delta, front, k1start, k1end, k2start, k2end, k2Offset, k1Offset, x1, x2, y1, y2, d, k1, k2; + text1Length = text1.length; + text2Length = text2.length; + maxD = Math.ceil((text1Length + text2Length) / 2); + vOffset = maxD; + vLength = 2 * maxD; + v1 = new Array(vLength); + v2 = new Array(vLength); + for (x = 0; x < vLength; x++) { + v1[x] = -1; + v2[x] = -1; + } + v1[vOffset + 1] = 0; + v2[vOffset + 1] = 0; + delta = text1Length - text2Length; + front = delta % 2 !== 0; + k1start = 0; + k1end = 0; + k2start = 0; + k2end = 0; + for (d = 0; d < maxD; d++) { + if (new Date().getTime() > deadline) { + break; + } + for (k1 = -d + k1start; k1 <= d - k1end; k1 += 2) { + k1Offset = vOffset + k1; + if (k1 === -d || k1 !== d && v1[k1Offset - 1] < v1[k1Offset + 1]) { + x1 = v1[k1Offset + 1]; + } else { + x1 = v1[k1Offset - 1] + 1; + } + y1 = x1 - k1; + while (x1 < text1Length && y1 < text2Length && text1.charAt(x1) === text2.charAt(y1)) { + x1++; + y1++; + } + v1[k1Offset] = x1; + if (x1 > text1Length) { + k1end += 2; + } else if (y1 > text2Length) { + k1start += 2; + } else if (front) { + k2Offset = vOffset + delta - k1; + if (k2Offset >= 0 && k2Offset < vLength && v2[k2Offset] !== -1) { + x2 = text1Length - v2[k2Offset]; + if (x1 >= x2) { + return this.diffBisectSplit(text1, text2, x1, y1, deadline); + } + } + } + } + for (k2 = -d + k2start; k2 <= d - k2end; k2 += 2) { + k2Offset = vOffset + k2; + if (k2 === -d || k2 !== d && v2[k2Offset - 1] < v2[k2Offset + 1]) { + x2 = v2[k2Offset + 1]; + } else { + x2 = v2[k2Offset - 1] + 1; + } + y2 = x2 - k2; + while (x2 < text1Length && y2 < text2Length && text1.charAt(text1Length - x2 - 1) === text2.charAt(text2Length - y2 - 1)) { + x2++; + y2++; + } + v2[k2Offset] = x2; + if (x2 > text1Length) { + k2end += 2; + } else if (y2 > text2Length) { + k2start += 2; + } else if (!front) { + k1Offset = vOffset + delta - k2; + if (k1Offset >= 0 && k1Offset < vLength && v1[k1Offset] !== -1) { + x1 = v1[k1Offset]; + y1 = vOffset + x1 - k1Offset; + x2 = text1Length - x2; + if (x1 >= x2) { + return this.diffBisectSplit(text1, text2, x1, y1, deadline); + } + } + } + } + } + return [ + [ + DIFF_DELETE, + text1 + ], + [ + DIFF_INSERT, + text2 + ] + ]; + }; + DiffMatchPatch.prototype.diffBisectSplit = function (text1, text2, x, y, deadline) { + var text1a, text1b, text2a, text2b, diffs, diffsb; + text1a = text1.substring(0, x); + text2a = text2.substring(0, y); + text1b = text1.substring(x); + text2b = text2.substring(y); + diffs = this.DiffMain(text1a, text2a, false, deadline); + diffsb = this.DiffMain(text1b, text2b, false, deadline); + return diffs.concat(diffsb); + }; + DiffMatchPatch.prototype.diffCleanupSemantic = function (diffs) { + var changes, equalities, equalitiesLength, lastequality, pointer, lengthInsertions2, lengthDeletions2, lengthInsertions1, lengthDeletions1, deletion, insertion, overlapLength1, overlapLength2; + changes = false; + equalities = []; + equalitiesLength = 0; + lastequality = null; + pointer = 0; + lengthInsertions1 = 0; + lengthDeletions1 = 0; + lengthInsertions2 = 0; + lengthDeletions2 = 0; + while (pointer < diffs.length) { + if (diffs[pointer][0] === DIFF_EQUAL) { + equalities[equalitiesLength++] = pointer; + lengthInsertions1 = lengthInsertions2; + lengthDeletions1 = lengthDeletions2; + lengthInsertions2 = 0; + lengthDeletions2 = 0; + lastequality = diffs[pointer][1]; + } else { + if (diffs[pointer][0] === DIFF_INSERT) { + lengthInsertions2 += diffs[pointer][1].length; + } else { + lengthDeletions2 += diffs[pointer][1].length; + } + if (lastequality && lastequality.length <= Math.max(lengthInsertions1, lengthDeletions1) && lastequality.length <= Math.max(lengthInsertions2, lengthDeletions2)) { + diffs.splice(equalities[equalitiesLength - 1], 0, [ + DIFF_DELETE, + lastequality + ]); + diffs[equalities[equalitiesLength - 1] + 1][0] = DIFF_INSERT; + equalitiesLength--; + equalitiesLength--; + pointer = equalitiesLength > 0 ? equalities[equalitiesLength - 1] : -1; + lengthInsertions1 = 0; + lengthDeletions1 = 0; + lengthInsertions2 = 0; + lengthDeletions2 = 0; + lastequality = null; + changes = true; + } + } + pointer++; + } + if (changes) { + this.diffCleanupMerge(diffs); + } + pointer = 1; + while (pointer < diffs.length) { + if (diffs[pointer - 1][0] === DIFF_DELETE && diffs[pointer][0] === DIFF_INSERT) { + deletion = diffs[pointer - 1][1]; + insertion = diffs[pointer][1]; + overlapLength1 = this.diffCommonOverlap(deletion, insertion); + overlapLength2 = this.diffCommonOverlap(insertion, deletion); + if (overlapLength1 >= overlapLength2) { + if (overlapLength1 >= deletion.length / 2 || overlapLength1 >= insertion.length / 2) { + diffs.splice(pointer, 0, [ + DIFF_EQUAL, + insertion.substring(0, overlapLength1) + ]); + diffs[pointer - 1][1] = deletion.substring(0, deletion.length - overlapLength1); + diffs[pointer + 1][1] = insertion.substring(overlapLength1); + pointer++; + } + } else { + if (overlapLength2 >= deletion.length / 2 || overlapLength2 >= insertion.length / 2) { + diffs.splice(pointer, 0, [ + DIFF_EQUAL, + deletion.substring(0, overlapLength2) + ]); + diffs[pointer - 1][0] = DIFF_INSERT; + diffs[pointer - 1][1] = insertion.substring(0, insertion.length - overlapLength2); + diffs[pointer + 1][0] = DIFF_DELETE; + diffs[pointer + 1][1] = deletion.substring(overlapLength2); + pointer++; + } + } + pointer++; + } + pointer++; + } + }; + DiffMatchPatch.prototype.diffCommonOverlap = function (text1, text2) { + var text1Length, text2Length, textLength, best, length, pattern, found; + text1Length = text1.length; + text2Length = text2.length; + if (text1Length === 0 || text2Length === 0) { + return 0; + } + if (text1Length > text2Length) { + text1 = text1.substring(text1Length - text2Length); + } else if (text1Length < text2Length) { + text2 = text2.substring(0, text1Length); + } + textLength = Math.min(text1Length, text2Length); + if (text1 === text2) { + return textLength; + } + best = 0; + length = 1; + while (true) { + pattern = text1.substring(textLength - length); + found = text2.indexOf(pattern); + if (found === -1) { + return best; + } + length += found; + if (found === 0 || text1.substring(textLength - length) === text2.substring(0, length)) { + best = length; + length++; + } + } + }; + DiffMatchPatch.prototype.diffLinesToChars = function (text1, text2) { + var lineArray, lineHash, chars1, chars2; + lineArray = []; + lineHash = {}; + lineArray[0] = ''; + function diffLinesToCharsMunge(text) { + var chars, lineStart, lineEnd, lineArrayLength, line; + chars = ''; + lineStart = 0; + lineEnd = -1; + lineArrayLength = lineArray.length; + while (lineEnd < text.length - 1) { + lineEnd = text.indexOf('\n', lineStart); + if (lineEnd === -1) { + lineEnd = text.length - 1; + } + line = text.substring(lineStart, lineEnd + 1); + lineStart = lineEnd + 1; + var lineHashExists = lineHash.hasOwnProperty ? lineHash.hasOwnProperty(line) : lineHash[line] !== undefined; + if (lineHashExists) { + chars += String.fromCharCode(lineHash[line]); + } else { + chars += String.fromCharCode(lineArrayLength); + lineHash[line] = lineArrayLength; + lineArray[lineArrayLength++] = line; + } + } + return chars; + } + chars1 = diffLinesToCharsMunge(text1); + chars2 = diffLinesToCharsMunge(text2); + return { + chars1: chars1, + chars2: chars2, + lineArray: lineArray + }; + }; + DiffMatchPatch.prototype.diffCharsToLines = function (diffs, lineArray) { + var x, chars, text, y; + for (x = 0; x < diffs.length; x++) { + chars = diffs[x][1]; + text = []; + for (y = 0; y < chars.length; y++) { + text[y] = lineArray[chars.charCodeAt(y)]; + } + diffs[x][1] = text.join(''); + } + }; + DiffMatchPatch.prototype.diffCleanupMerge = function (diffs) { + var pointer, countDelete, countInsert, textInsert, textDelete, commonlength, changes, diffPointer, position; + diffs.push([ + DIFF_EQUAL, + '' + ]); + pointer = 0; + countDelete = 0; + countInsert = 0; + textDelete = ''; + textInsert = ''; + while (pointer < diffs.length) { + switch (diffs[pointer][0]) { + case DIFF_INSERT: + countInsert++; + textInsert += diffs[pointer][1]; + pointer++; + break; + case DIFF_DELETE: + countDelete++; + textDelete += diffs[pointer][1]; + pointer++; + break; + case DIFF_EQUAL: + if (countDelete + countInsert > 1) { + if (countDelete !== 0 && countInsert !== 0) { + commonlength = this.diffCommonPrefix(textInsert, textDelete); + if (commonlength !== 0) { + if (pointer - countDelete - countInsert > 0 && diffs[pointer - countDelete - countInsert - 1][0] === DIFF_EQUAL) { + diffs[pointer - countDelete - countInsert - 1][1] += textInsert.substring(0, commonlength); + } else { + diffs.splice(0, 0, [ + DIFF_EQUAL, + textInsert.substring(0, commonlength) + ]); + pointer++; + } + textInsert = textInsert.substring(commonlength); + textDelete = textDelete.substring(commonlength); + } + commonlength = this.diffCommonSuffix(textInsert, textDelete); + if (commonlength !== 0) { + diffs[pointer][1] = textInsert.substring(textInsert.length - commonlength) + diffs[pointer][1]; + textInsert = textInsert.substring(0, textInsert.length - commonlength); + textDelete = textDelete.substring(0, textDelete.length - commonlength); + } + } + if (countDelete === 0) { + diffs.splice(pointer - countInsert, countDelete + countInsert, [ + DIFF_INSERT, + textInsert + ]); + } else if (countInsert === 0) { + diffs.splice(pointer - countDelete, countDelete + countInsert, [ + DIFF_DELETE, + textDelete + ]); + } else { + diffs.splice(pointer - countDelete - countInsert, countDelete + countInsert, [ + DIFF_DELETE, + textDelete + ], [ + DIFF_INSERT, + textInsert + ]); + } + pointer = pointer - countDelete - countInsert + (countDelete ? 1 : 0) + (countInsert ? 1 : 0) + 1; + } else if (pointer !== 0 && diffs[pointer - 1][0] === DIFF_EQUAL) { + diffs[pointer - 1][1] += diffs[pointer][1]; + diffs.splice(pointer, 1); + } else { + pointer++; + } + countInsert = 0; + countDelete = 0; + textDelete = ''; + textInsert = ''; + break; + } + } + if (diffs[diffs.length - 1][1] === '') { + diffs.pop(); + } + changes = false; + pointer = 1; + while (pointer < diffs.length - 1) { + if (diffs[pointer - 1][0] === DIFF_EQUAL && diffs[pointer + 1][0] === DIFF_EQUAL) { + diffPointer = diffs[pointer][1]; + position = diffPointer.substring(diffPointer.length - diffs[pointer - 1][1].length); + if (position === diffs[pointer - 1][1]) { + diffs[pointer][1] = diffs[pointer - 1][1] + diffs[pointer][1].substring(0, diffs[pointer][1].length - diffs[pointer - 1][1].length); + diffs[pointer + 1][1] = diffs[pointer - 1][1] + diffs[pointer + 1][1]; + diffs.splice(pointer - 1, 1); + changes = true; + } else if (diffPointer.substring(0, diffs[pointer + 1][1].length) === diffs[pointer + 1][1]) { + diffs[pointer - 1][1] += diffs[pointer + 1][1]; + diffs[pointer][1] = diffs[pointer][1].substring(diffs[pointer + 1][1].length) + diffs[pointer + 1][1]; + diffs.splice(pointer + 1, 1); + changes = true; + } + } + pointer++; + } + if (changes) { + this.diffCleanupMerge(diffs); + } + }; + return function (o, n) { + var diff, output, text; + diff = new DiffMatchPatch(); + output = diff.DiffMain(o, n); + diff.diffCleanupEfficiency(output); + text = diff.diffPrettyHtml(output); + return text; + }; + }(); +}(function () { + return this; +}())); +/*can-ajax@2.1.1#test/qunit*/ +define('can-ajax@2.1.1#test/qunit', [ + 'require', + 'exports', + 'module', + 'qunitjs', + 'steal-qunit' +], function (require, exports, module) { + 'use strict'; + var testType = typeof process !== 'undefined' && process.env.TEST; + var isMochaQUnitUI = testType === 'mocha'; + var isQunit = testType === 'qunit'; + if (isMochaQUnitUI) { + QUnit.assert.async = function () { + QUnit.stop(); + return function done(error) { + if (error) { + return QUnit.ok(false, '' + error); + } + QUnit.start(); + }; + }; + QUnit.test = test; + module.exports = QUnit; + } else if (isQunit) { + module.exports = require('qunitjs'); + } else { + module.exports = require('steal-qunit'); + } +}); +/*can-ajax@2.1.1#test/helpers*/ +define('can-ajax@2.1.1#test/helpers', [ + 'require', + 'exports', + 'module', + 'can-globals/global/global' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var getGlobal = require('can-globals/global/global'); + function isProduction() { + var root = getGlobal(); + if (root.System) { + return root.System.env.indexOf('production') !== -1; + } + if (root.process) { + var nodeEnv = root.process.env.NODE_ENV; + return nodeEnv === 'production' || nodeEnv === 'window-production'; + } + return false; + } + function isServer() { + var root = getGlobal(); + var testType = root.process && root.process.env.TEST; + return testType === 'qunit'; + } + module.exports = { + isProduction: isProduction, + isServer: isServer + }; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-ajax@2.1.1#can-ajax-test*/ +define('can-ajax@2.1.1#can-ajax-test', [ + 'require', + 'exports', + 'module', + './can-ajax', + 'can-namespace', + 'can-make-map', + 'can-globals/global/global', + 'can-parse-uri', + './test/qunit', + './test/helpers' +], function (require, exports, module) { + (function (global, __dirname, require, exports, module) { + 'use strict'; + var ajax = require('./can-ajax'); + var namespace = require('can-namespace'); + var makeMap = require('can-make-map'); + var GLOBAL = require('can-globals/global/global'); + var parseURI = require('can-parse-uri'); + var QUnit = require('./test/qunit'); + var helpers = require('./test/helpers'); + var isMainCanTest = typeof System === 'object' && System.env !== 'canjs-test'; + var hasLocalServer = !helpers.isServer() && !helpers.isProduction(); + QUnit.module('can-ajax'); + var makeFixture = function (XHR) { + var oldXhr = window.XMLHttpRequest || window.ActiveXObject; + if (window.XMLHttpRequest) { + window.XMLHttpRequest = XHR; + } else if (window.ActiveXObject) { + window.ActiveXObject = XHR; + } + return function restoreXHR() { + if (window.XMLHttpRequest) { + window.XMLHttpRequest = oldXhr; + } else if (window.ActiveXObject) { + window.ActiveXObject = oldXhr; + } + }; + }; + var makePredicateContains = function (str) { + var obj = makeMap(str); + return function (val) { + return obj[val]; + }; + }; + if (hasLocalServer) { + QUnit.test('basic get request', function (assert) { + var done = assert.async(); + ajax({ + type: 'get', + url: __dirname + '/can-ajax-test-result.json' + }).then(function (resp) { + assert.equal(resp.message, 'VALUE'); + done(); + }); + }); + } + QUnit.test('added to namespace (#99)', function (assert) { + assert.equal(namespace.ajax, ajax); + }); + if (hasLocalServer) { + QUnit.test('GET requests with dataType parse JSON (#106)', function (assert) { + var done = assert.async(); + ajax({ + type: 'get', + url: __dirname + '/can-ajax-test-result.txt', + dataType: 'json' + }).then(function (resp) { + assert.equal(resp.message, 'VALUE'); + done(); + }); + }); + } + QUnit.test('ignores case of type parameter for a post request (#100)', function (assert) { + var done = assert.async(); + var requestHeaders = { CONTENT_TYPE: 'Content-Type' }, restore = makeFixture(function () { + this.open = function (type, url) { + }; + this.send = function () { + this.readyState = 4; + this.status = 200; + this.onreadystatechange(); + }; + this.setRequestHeader = function (header, value) { + if (header === requestHeaders.CONTENT_TYPE) { + var o = {}; + o[header] = value; + this.responseText = JSON.stringify(o); + } + }; + }); + ajax({ + type: 'post', + url: 'http://anotherdomain.com/foo', + data: { bar: 'qux' } + }).then(function (value) { + assert.equal(value[requestHeaders.CONTENT_TYPE], 'application/x-www-form-urlencoded'); + }, function (reason) { + assert.notOk(reason, 'request failed with reason = ', reason); + }).then(function () { + restore(); + done(); + }); + }); + QUnit.test('url encodes GET requests when no contentType', function (assert) { + var done = assert.async(); + var restore = makeFixture(function () { + var o = {}; + this.open = function (type, url) { + o.url = url; + }; + this.send = function (data) { + o.data = data; + this.readyState = 4; + this.status = 200; + this.responseText = JSON.stringify(o); + this.onreadystatechange(); + }; + this.setRequestHeader = function (header, value) { + if (header === 'Content-Type') { + o[header] = value; + } + }; + }); + ajax({ + type: 'get', + url: 'http://anotherdomain.com/foo', + data: { foo: 'bar' } + }).then(function (value) { + assert.equal(value['Content-Type'], 'application/x-www-form-urlencoded'); + assert.equal(value.data, undefined, 'No data provided because it\'s a GET'); + assert.equal(value.url, 'http://anotherdomain.com/foo?foo=bar'); + }, function (reason) { + assert.notOk(reason, 'request failed with reason = ', reason); + }).then(function () { + restore(); + done(); + }); + }); + QUnit.test('Stringifies GET requests when contentType=application/json', function (assert) { + var done = assert.async(); + var restore = makeFixture(function () { + var o = {}; + this.open = function (type, url) { + o.url = url; + }; + this.send = function (data) { + o.data = data; + this.readyState = 4; + this.status = 200; + this.responseText = JSON.stringify(o); + this.onreadystatechange(); + }; + this.setRequestHeader = function (header, value) { + if (header === 'Content-Type') { + o[header] = value; + } + }; + }); + ajax({ + type: 'get', + url: 'http://anotherdomain.com/foo', + data: { foo: 'bar' }, + contentType: 'application/json' + }).then(function (value) { + assert.equal(value['Content-Type'], 'application/json'); + assert.equal(value.data, undefined, 'No data provided because it\'s a GET'); + assert.equal(value.url, 'http://anotherdomain.com/foo?{"foo":"bar"}'); + }, function (reason) { + assert.notOk(reason, 'request failed with reason = ', reason); + }).then(function () { + restore(); + done(); + }); + }); + QUnit.test('Stringifies POST requests when there is no contentType', function (assert) { + var done = assert.async(); + var restore = makeFixture(function () { + var o = {}; + this.open = function (type, url) { + o.url = url; + }; + this.send = function (data) { + o.data = data; + this.readyState = 4; + this.status = 200; + this.responseText = JSON.stringify(o); + this.onreadystatechange(); + }; + this.setRequestHeader = function (header, value) { + if (header === 'Content-Type') { + o[header] = value; + } + }; + }); + var origin = parseURI(GLOBAL().location.href); + var url = origin.protocol + origin.authority + '/foo'; + ajax({ + type: 'post', + url: url, + data: { foo: 'bar' } + }).then(function (value) { + assert.equal(value['Content-Type'], 'application/json'); + assert.equal(value.data, '{"foo":"bar"}', 'Data was stringified'); + assert.equal(value.url, url); + }, function (reason) { + assert.notOk(reason, 'request failed with reason = ', reason); + }).then(function () { + restore(); + done(); + }); + }); + QUnit.test('url encodes POST requests when contentType=application/x-www-form-urlencoded', function (assert) { + var done = assert.async(); + var restore = makeFixture(function () { + var o = {}; + this.open = function (type, url) { + o.url = url; + }; + this.send = function (data) { + o.data = data; + this.readyState = 4; + this.status = 200; + this.responseText = JSON.stringify(o); + this.onreadystatechange(); + }; + this.setRequestHeader = function (header, value) { + if (header === 'Content-Type') { + o[header] = value; + } + }; + }); + ajax({ + type: 'post', + url: 'http://anotherdomain.com/foo', + data: { foo: 'bar' }, + contentType: 'application/x-www-form-urlencoded' + }).then(function (value) { + assert.equal(value['Content-Type'], 'application/x-www-form-urlencoded'); + assert.equal(value.data, 'foo=bar', 'Data was url encoded'); + assert.equal(value.url, 'http://anotherdomain.com/foo'); + }, function (reason) { + assert.notOk(reason, 'request failed with reason = ', reason); + }).then(function () { + restore(); + done(); + }); + }); + if (typeof XDomainRequest === 'undefined') { + QUnit.test('cross domain post request should change data to form data (#90)', function (assert) { + var done = assert.async(); + var headers = {}, restore = makeFixture(function () { + this.open = function (type, url) { + }; + this.send = function () { + this.readyState = 4; + this.status = 204; + this.responseText = ''; + this.onreadystatechange(); + }; + this.setRequestHeader = function (header, value) { + headers[header] = value; + }; + }); + ajax({ + type: 'POST', + url: 'https://httpbin.org/post', + data: { 'message': 'VALUE' }, + dataType: 'application/json' + }).then(function (resp) { + QUnit.deepEqual(headers, { 'Content-Type': 'application/x-www-form-urlencoded' }); + restore(); + done(); + }); + }); + QUnit.test('GET CORS should be a simple request - without a preflight (#187)', function (assert) { + var done = assert.async(); + var isSimpleRequest = true, restore; + var isSimpleMethod = makePredicateContains('GET,POST,HEAD'); + var isSimpleHeader = makePredicateContains('Accept,Accept-Language,Content-Language,Content-Type,DPR,Downlink,Save-Data,Viewport-Width,Width'); + var isSimpleContentType = makePredicateContains('application/x-www-form-urlencoded,multipart/form-data,text/plain'); + restore = makeFixture(function () { + this.open = function (type, url) { + if (!isSimpleMethod(type)) { + isSimpleRequest = false; + } + }; + var response = {}; + this.send = function () { + this.responseText = JSON.stringify(response); + this.readyState = 4; + this.status = 200; + this.onreadystatechange(); + }; + this.setRequestHeader = function (header, value) { + if (header === 'Content-Type' && !isSimpleContentType(value)) { + isSimpleRequest = false; + } + if (isSimpleRequest && !isSimpleHeader(header)) { + isSimpleRequest = false; + } + response[header] = value; + }; + }); + ajax({ + url: 'http://query.yahooapis.com/v1/public/yql', + data: { + q: 'select * from geo.places where text="sunnyvale, ca"', + format: 'json' + } + }).then(function (response) { + assert.ok(isSimpleRequest, 'CORS GET is simple'); + restore(); + done(); + }, function (err) { + assert.ok(false, 'Should be resolved'); + restore(); + done(); + }); + }); + } + if (isMainCanTest && hasLocalServer) { + QUnit.test('abort', function (assert) { + var done = assert.async(); + var promise = ajax({ + type: 'get', + url: __dirname + '/can-ajax-test-result.json' + }); + promise.catch(function (xhr) { + if (xhr instanceof Error) { + assert.equal(xhr.message, 'Could not complete the operation due to error c00c023f.'); + done(); + } else { + setTimeout(function () { + assert.equal(xhr.readyState, 0, 'aborts the promise'); + done(); + }, 50); + } + }); + promise.abort(); + }); + } + QUnit.test('crossDomain is true for relative requests', function (assert) { + var done = assert.async(); + var headers = {}, restore = makeFixture(function () { + this.open = function (type, url) { + }; + this.send = function () { + this.readyState = 4; + this.status = 200; + this.responseText = JSON.stringify({ great: 'success' }); + this.onreadystatechange(); + }; + this.setRequestHeader = function (header, value) { + headers[header] = value; + }; + }); + ajax({ + type: 'post', + url: '/foo', + data: { bar: 'qux' }, + dataType: 'json' + }).then(function (value) { + assert.deepEqual(headers, { + 'Content-Type': 'application/json', + 'X-Requested-With': 'XMLHttpRequest' + }); + }, function (reason) { + assert.notOk(reason, 'request failed with reason = ', reason); + }).then(function () { + restore(); + done(); + }); + }); + QUnit.test('handles 204 No Content responses when expecting JSON', function (assert) { + var done = assert.async(); + var headers = {}, restore = makeFixture(function () { + this.open = function (type, url) { + }; + this.send = function () { + this.readyState = 4; + this.status = 204; + this.responseText = ''; + this.onreadystatechange(); + }; + this.setRequestHeader = function (header, value) { + headers[header] = value; + }; + }); + ajax({ + type: 'delete', + url: '/foo', + data: { id: 'qux' }, + dataType: 'json' + }).then(function () { + assert.deepEqual(headers, { + 'Content-Type': 'application/json', + 'X-Requested-With': 'XMLHttpRequest' + }); + }, function (reason) { + assert.notOk(reason, 'request failed with reason = ', reason); + }).then(function () { + restore(); + done(); + }); + }); + QUnit.test('handles responseText containing text when expecting JSON (#46)', function (assert) { + var done = assert.async(); + var NOT_FOUND_CODE = 404; + var NOT_FOUND_MSG = 'NOT FOUND'; + var headers = {}, restore = makeFixture(function () { + this.open = function (type, url) { + }; + this.send = function () { + this.readyState = 4; + this.status = NOT_FOUND_CODE; + this.responseText = NOT_FOUND_MSG; + this.onreadystatechange(); + }; + this.setRequestHeader = function (header, value) { + headers[header] = value; + }; + }); + ajax({ + type: 'get', + url: '/foo', + dataType: 'json' + }).then(function (value) { + assert.notOk(value, 'success callback call not expected'); + }, function (xhr) { + assert.equal(xhr.status, 404); + assert.equal(xhr.responseText, NOT_FOUND_MSG); + }).then(function () { + restore(); + done(); + }); + }); + if (hasLocalServer) { + QUnit.test('correctly serializes null and undefined values (#177)', function (assert) { + var done = assert.async(); + ajax({ + type: 'get', + url: __dirname + '/can-ajax-test-result.txt', + data: { foo: null } + }).then(function (resp) { + assert.equal(resp.message, 'VALUE'); + done(); + }); + }); + } + QUnit.test('It doesn\'t stringify FormData', function (assert) { + var done = assert.async(); + var headers = {}; + var formData = new FormData(); + formData.append('foo', 'bar'); + var restore = makeFixture(function () { + var o = {}; + this.open = function (type, url) { + o.url = url; + }; + this.send = function (data) { + o.data = data; + this.readyState = 4; + this.status = 200; + this.responseText = JSON.stringify(o); + this.onreadystatechange(); + }; + this.setRequestHeader = function (header, value) { + if (header === 'Content-Type') { + o[header] = value; + } + }; + }); + var origin = parseURI(GLOBAL().location.href); + var url = origin.protocol + origin.authority + '/foo'; + ajax({ + type: 'post', + url: url, + data: formData + }).then(function (value) { + assert.equal(value['Content-Type'], 'application/json'); + assert.equal(value.url, url); + }, function (reason) { + assert.notOk(reason, 'request failed with reason = ', reason); + }).then(function () { + restore(); + done(); + }); + }); + QUnit.test('beforsend', function (assert) { + var done = assert.async(); + var headers = {}, restore = makeFixture(function () { + this.open = function (type, url) { + }; + this.send = function () { + this.readyState = 4; + this.status = 204; + this.responseText = ''; + this.onreadystatechange(); + }; + this.setRequestHeader = function (header, value) { + headers[header] = value; + }; + }); + ajax({ + type: 'post', + url: '/foo', + data: { id: 'qux' }, + dataType: 'json', + beforeSend: function (xhr) { + xhr.setRequestHeader('Authorization', 'Bearer 123'); + } + }).then(function (value) { + assert.ok(headers.hasOwnProperty('Authorization'), 'custom header set'); + }, function (reason) { + assert.notOk(reason, 'request failed with reason = ', reason); + }).then(function () { + restore(); + done(); + }); + }); + }(function () { + return this; + }(), '/', require, exports, module)); +}); +/*can-assign@1.3.1#can-assign-test*/ +define('can-assign@1.3.1#can-assign-test', [ + 'require', + 'exports', + 'module', + './can-assign', + 'steal-qunit' +], function (require, exports, module) { + var assign = require('./can-assign'); + var QUnit = require('steal-qunit'); + QUnit.module('can-assign'); + QUnit.test('Assign all properties to an object', function () { + var a = { + a: 1, + b: 2, + d: 3 + }; + var b = { + a: 1, + b: 3, + c: 2 + }; + var expected = { + a: 1, + b: 3, + c: 2, + d: 3 + }; + var actual = assign(a, b); + for (var prop in actual) { + equal(expected[prop], actual[prop]); + } + }); + QUnit.test('Works with readonly properties', function () { + var obj = {}; + Object.defineProperty(obj, 'a', { + value: 'a', + writable: false + }); + Object.defineProperty(obj, 'b', { + value: 'b', + writable: true + }); + Object.defineProperty(obj, 'c', { + get: function () { + return 'c'; + }, + set: function (value) { + this.b = value; + }, + configurable: true + }); + try { + assign(obj, { + a: 'c', + b: 'f', + d: 'd' + }); + QUnit.equal(obj.a, 'a'); + QUnit.equal(obj.b, 'f'); + QUnit.equal(obj.c, 'c'); + QUnit.equal(obj.d, 'd'); + assign(obj, { c: 'h' }); + QUnit.equal(obj.a, 'a'); + QUnit.equal(obj.b, 'h'); + QUnit.equal(obj.c, 'c'); + QUnit.equal(obj.d, 'd'); + } catch (err) { + QUnit.ok(false, err); + } + }); +}); +/*can-bind@1.1.1#test/helpers*/ +define('can-bind@1.1.1#test/helpers', function (require, exports, module) { + function incrementByOne(newValue) { + return newValue + 1; + } + function protectAgainstInfiniteLoops(func) { + var counter = 0; + return function () { + counter += 1; + if (counter > 10) { + throw new Error('Infinite loop'); + } + return func.apply(null, arguments); + }; + } + module.exports = { + incrementByOne: incrementByOne, + protectAgainstInfiniteLoops: protectAgainstInfiniteLoops, + moduleHooks: { + setup: function () { + this.groupCollapsed = console.groupCollapsed; + if (this.groupCollapsed) { + console.groupCollapsed = null; + } + }, + teardown: function () { + if (this.groupCollapsed) { + console.groupCollapsed = this.groupCollapsed; + } + } + } + }; +}); +/*can-bind@1.1.1#test/core*/ +define('can-bind@1.1.1#test/core', [ + 'require', + 'exports', + 'module', + '../can-bind', + 'can-reflect', + 'can-reflect-dependencies', + 'can-test-helpers', + './helpers', + 'can-observation', + 'steal-qunit', + 'can-simple-observable/settable/settable', + 'can-simple-map', + 'can-simple-observable' +], function (require, exports, module) { + var Bind = require('../can-bind'); + var canReflect = require('can-reflect'); + var canReflectDeps = require('can-reflect-dependencies'); + var canTestHelpers = require('can-test-helpers'); + var helpers = require('./helpers'); + var Observation = require('can-observation'); + var QUnit = require('steal-qunit'); + var SettableObservable = require('can-simple-observable/settable/settable'); + var SimpleMap = require('can-simple-map'); + var SimpleObservable = require('can-simple-observable'); + QUnit.module('can-bind core', helpers.moduleHooks); + QUnit.test('one-way binding to child', function (assert) { + var parentValue = new SimpleObservable(0); + var parent = new Observation(function () { + return parentValue.get(); + }); + var child = new SimpleObservable(0); + var binding = new Bind({ + child: child, + parent: parent + }); + binding.start(); + parentValue.set(15); + assert.equal(canReflect.getValue(child), 15, 'child updates'); + child.set(22); + assert.equal(canReflect.getValue(parent), 15, 'parent does not update'); + binding.stop(); + parentValue.set(45); + assert.equal(canReflect.getValue(child), 22, 'parent listener correctly turned off'); + }); + canTestHelpers.dev.devOnlyTest('one-way binding to child - dependency data', function (assert) { + var parentValue = new SimpleObservable(0); + var parent = new Observation(function () { + return parentValue.get(); + }); + var child = new SimpleObservable(0); + var binding = new Bind({ + child: child, + parent: parent + }); + binding.start(); + var childDepData = canReflectDeps.getDependencyDataOf(child); + var valueDependencies = new Set(); + valueDependencies.add(parent); + assert.deepEqual(childDepData, { whatChangesMe: { mutate: { valueDependencies: valueDependencies } } }, 'child observable has the correct mutation dependencies'); + var parentDepData = canReflectDeps.getDependencyDataOf(parent); + assert.deepEqual(parentDepData, { + whatChangesMe: { derive: { valueDependencies: new Set([parentValue]) } }, + whatIChange: { mutate: { valueDependencies: new Set([child]) } } + }, 'parent observable has the correct mutation dependencies'); + binding.stop(); + childDepData = canReflectDeps.getDependencyDataOf(child); + assert.equal(childDepData, undefined, 'child observable has no mutation dependencies after stop()'); + parentDepData = canReflectDeps.getDependencyDataOf(parent); + assert.equal(parentDepData, undefined, 'parent observable has no mutation dependencies after stop()'); + }); + QUnit.test('one-way binding to parent', function (assert) { + var parent = new SimpleObservable(0); + var childValue = new SimpleObservable(0); + var child = new Observation(function () { + return childValue.get(); + }); + var binding = new Bind({ + child: child, + parent: parent + }); + binding.start(); + parent.set(15); + assert.equal(canReflect.getValue(child), 0, 'child does not update'); + childValue.set(22); + assert.equal(canReflect.getValue(parent), 22, 'parent updates'); + binding.stop(); + childValue.set(58); + assert.equal(canReflect.getValue(parent), 22, 'child listener correctly turned off'); + }); + canTestHelpers.dev.devOnlyTest('one-way binding to parent - dependency data', function (assert) { + var parent = new SimpleObservable(0); + var childValue = new SimpleObservable(0); + var child = new Observation(function () { + return childValue.get(); + }); + var binding = new Bind({ + child: child, + parent: parent + }); + binding.start(); + var childDepData = canReflectDeps.getDependencyDataOf(child); + assert.deepEqual(childDepData, { + whatChangesMe: { derive: { valueDependencies: new Set([childValue]) } }, + whatIChange: { mutate: { valueDependencies: new Set([parent]) } } + }, 'child observable has the correct mutation dependencies'); + var parentDepData = canReflectDeps.getDependencyDataOf(parent); + assert.deepEqual(parentDepData, { whatChangesMe: { mutate: { valueDependencies: new Set([child]) } } }, 'parent observable has the correct mutation dependencies'); + binding.stop(); + childDepData = canReflectDeps.getDependencyDataOf(child); + assert.equal(childDepData, undefined, 'child observable has no mutation dependencies after stop()'); + parentDepData = canReflectDeps.getDependencyDataOf(parent); + assert.equal(parentDepData, undefined, 'parent observable has no mutation dependencies after stop()'); + }); + QUnit.test('basic two-way binding', function (assert) { + var parent = new SimpleObservable(0); + var child = new SimpleObservable(0); + var binding = new Bind({ + child: child, + parent: parent + }); + binding.start(); + parent.set(15); + assert.equal(canReflect.getValue(child), 15, 'child updates'); + child.set(22); + assert.equal(canReflect.getValue(parent), 22, 'parent updates'); + assert.equal(child.handlers.get([]).length, 1, '1 child listener before calling stop()'); + assert.equal(parent.handlers.get([]).length, 1, '1 parent listener before calling stop()'); + binding.stop(); + assert.equal(child.handlers.get([]).length, 0, '0 child listeners after calling stop()'); + assert.equal(parent.handlers.get([]).length, 0, '0 parent listeners after calling stop()'); + parent.set(45); + assert.equal(canReflect.getValue(child), 22, 'parent listener correctly turned off'); + child.set(58); + assert.equal(canReflect.getValue(parent), 45, 'child listener correctly turned off'); + }); + canTestHelpers.dev.devOnlyTest('basic two-way binding - dependency data', function (assert) { + var parent = new SimpleObservable(0); + var child = new SimpleObservable(0); + var binding = new Bind({ + child: child, + parent: parent + }); + binding.start(); + var childDepData = canReflectDeps.getDependencyDataOf(child); + assert.deepEqual(childDepData, { + whatChangesMe: { mutate: { valueDependencies: new Set([parent]) } }, + whatIChange: { mutate: { valueDependencies: new Set([parent]) } } + }, 'child observable has the correct mutation dependencies'); + var parentDepData = canReflectDeps.getDependencyDataOf(parent); + assert.deepEqual(parentDepData, { + whatChangesMe: { mutate: { valueDependencies: new Set([child]) } }, + whatIChange: { mutate: { valueDependencies: new Set([child]) } } + }, 'parent observable has the correct mutation dependencies'); + binding.stop(); + childDepData = canReflectDeps.getDependencyDataOf(child); + assert.equal(childDepData, undefined, 'child observable has no mutation dependencies after stop()'); + parentDepData = canReflectDeps.getDependencyDataOf(parent); + assert.equal(parentDepData, undefined, 'parent observable has no mutation dependencies after stop()'); + }); + canTestHelpers.dev.devOnlyTest('updateChildName and updateParentName options', function (assert) { + var parent = new SimpleObservable(0); + var child = new SimpleObservable(0); + var binding = new Bind({ + child: child, + parent: parent, + updateChildName: 'custom child name', + updateParentName: 'custom parent name' + }); + assert.equal(binding._updateChild.name, 'custom child name', 'child name is correct'); + assert.equal(binding._updateParent.name, 'custom parent name', 'parent name is correct'); + }); + QUnit.test('two-way binding with both values undefined', function (assert) { + var child = new SimpleObservable(undefined); + var parent = new SimpleObservable(undefined); + var setChildWasCalled = false; + var binding = new Bind({ + child: child, + parent: parent, + setChild: function () { + setChildWasCalled = true; + } + }); + binding.start(); + assert.equal(setChildWasCalled, true, 'setChild was called'); + binding.stop(); + }); + QUnit.test('two-way binding updates are ignored after calling stop()', function (assert) { + var child = new SimpleObservable(15); + var parent = new SimpleObservable(15); + var binding = new Bind({ + child: child, + parent: parent + }); + var turnOffBinding = function () { + binding.stop(); + }; + canReflect.onValue(parent, turnOffBinding, 'domUI'); + binding.start(); + parent.set(undefined); + assert.equal(canReflect.getValue(child), 15, 'child stays the same'); + assert.equal(canReflect.getValue(parent), undefined, 'parent stays the same'); + canReflect.offValue(parent, turnOffBinding, 'domUI'); + }); + QUnit.test('parentValue property', function (assert) { + var parent = new SimpleObservable(15); + var child = new SimpleObservable(22); + var binding = new Bind({ + child: child, + parent: parent, + priority: 15 + }); + assert.equal(binding.parentValue, 15, 'can get parentValue'); + }); + QUnit.test('priority option', function (assert) { + var parent = new SettableObservable(helpers.incrementByOne, null, 0); + var child = new SettableObservable(helpers.incrementByOne, null, 0); + new Bind({ + child: child, + parent: parent, + priority: 15 + }); + assert.equal(canReflect.getPriority(child), 15, 'child priority set'); + assert.equal(canReflect.getPriority(parent), 15, 'parent priority set'); + }); + QUnit.test('setChild and setParent options', function (assert) { + var parent = new SimpleObservable(undefined); + var map = new SimpleMap({ prop: 'value' }); + var child = new Observation(function () { + return map.serialize(); + }); + var binding = new Bind({ + child: child, + parent: parent, + setChild: function (newValue) { + var split = newValue.split('='); + var objectValue = {}; + objectValue[split[0]] = split[1]; + map.set(objectValue); + }, + setParent: function (newValue) { + parent.set('prop=' + newValue.prop); + } + }); + binding.start(); + parent.set('prop=15'); + assert.deepEqual(canReflect.getValue(child), { prop: '15' }, 'child updates'); + map.set({ prop: 22 }); + assert.equal(canReflect.getValue(parent), 'prop=22', 'parent updates'); + binding.stop(); + parent.set('prop=45'); + assert.deepEqual(canReflect.getValue(child), { prop: 22 }, 'parent listener correctly turned off'); + }); +}); +/*can-bind@1.1.1#test/cycles-and-sticky*/ +define('can-bind@1.1.1#test/cycles-and-sticky', [ + 'require', + 'exports', + 'module', + '../can-bind', + 'can-reflect', + 'can-test-helpers', + './helpers', + 'steal-qunit', + 'can-simple-observable/settable/settable', + 'can-simple-observable' +], function (require, exports, module) { + var Bind = require('../can-bind'); + var canReflect = require('can-reflect'); + var canTestHelpers = require('can-test-helpers'); + var helpers = require('./helpers'); + var QUnit = require('steal-qunit'); + var SettableObservable = require('can-simple-observable/settable/settable'); + var SimpleObservable = require('can-simple-observable'); + QUnit.module('can-bind cycles and sticky', helpers.moduleHooks); + QUnit.test('two-way binding with childSticksToParent', function (assert) { + var child = new SimpleObservable(0); + var parent = new SimpleObservable(0); + canReflect.assignSymbols(parent, { + 'can.setValue': function (newVal) { + if (newVal !== undefined) { + this.set(newVal); + } + } + }); + var binding = new Bind({ + child: child, + parent: parent, + sticky: 'childSticksToParent' + }); + binding.start(); + child.set(15); + assert.equal(canReflect.getValue(child), 15, 'child updates'); + assert.equal(canReflect.getValue(parent), 15, 'parent updates'); + child.set(undefined); + assert.equal(canReflect.getValue(child), 15, 'child stays the same'); + assert.equal(canReflect.getValue(parent), 15, 'parent stays the same'); + binding.stop(); + }); + function cycleStickyTest(options) { + var child = options.child; + var cycles = options.cycles; + var expectedChild = options.expectedChild; + var expectedParent = options.expectedParent; + var parent = options.parent; + var sticky = options.sticky; + var binding = new Bind({ + child: child, + cycles: cycles, + onInitDoNotUpdateChild: true, + parent: parent, + sticky: sticky + }); + binding.start(); + if (options.startBySetting === 'child') { + child.set(1); + } else if (options.startBySetting === 'parent') { + parent.set(1); + } else { + throw new Error('No startBySetting option given'); + } + QUnit.equal(canReflect.getValue(parent), expectedParent, 'parent updates'); + QUnit.equal(canReflect.getValue(child), expectedChild, 'child updates'); + binding.stop(); + } + QUnit.test('cyclical two-way binding - 0 cycles not sticky', function () { + cycleStickyTest({ + parent: new SettableObservable(helpers.protectAgainstInfiniteLoops(helpers.incrementByOne), null, 0), + child: new SettableObservable(helpers.protectAgainstInfiniteLoops(helpers.incrementByOne), null, 0), + cycles: 0, + sticky: null, + startBySetting: 'parent', + expectedParent: 2, + expectedChild: 3 + }); + }); + canTestHelpers.dev.devOnlyTest('cyclical two-way binding - 0 cycles not sticky - warning in dev', function () { + var warningRegex = /Printing mutation history: 3 2/; + var teardown = canTestHelpers.dev.willWarn(warningRegex); + var parentSet = helpers.protectAgainstInfiniteLoops(helpers.incrementByOne); + Object.defineProperty(parentSet, 'name', { + value: 'PARENT', + configurable: true + }); + var parent = new SettableObservable(parentSet, null, 0); + var childSet = helpers.protectAgainstInfiniteLoops(helpers.incrementByOne); + Object.defineProperty(childSet, 'name', { + value: 'CHILD', + configurable: true + }); + var child = new SettableObservable(childSet, null, 0); + cycleStickyTest({ + parent: parent, + child: child, + startBySetting: 'parent', + expectedParent: 2, + expectedChild: 3 + }); + QUnit.equal(teardown(), 1, 'warning shown'); + }); + QUnit.test('cyclical two-way binding - 1 cycle not sticky', function () { + cycleStickyTest({ + parent: new SettableObservable(helpers.protectAgainstInfiniteLoops(helpers.incrementByOne), null, 0), + child: new SettableObservable(helpers.protectAgainstInfiniteLoops(helpers.incrementByOne), null, 0), + cycles: 1, + sticky: null, + startBySetting: 'parent', + expectedParent: 4, + expectedChild: 5 + }); + }); + QUnit.test('cyclical two-way binding - 2 cycles not sticky', function () { + cycleStickyTest({ + parent: new SettableObservable(helpers.protectAgainstInfiniteLoops(helpers.incrementByOne), null, 0), + child: new SettableObservable(helpers.protectAgainstInfiniteLoops(helpers.incrementByOne), null, 0), + cycles: 2, + sticky: null, + startBySetting: 'parent', + expectedParent: 6, + expectedChild: 7 + }); + }); + QUnit.test('two-way binding - 0 cycles childSticksToParent', function () { + cycleStickyTest({ + parent: new SettableObservable(helpers.protectAgainstInfiniteLoops(helpers.incrementByOne), null, -1), + child: new SimpleObservable(0), + cycles: 0, + sticky: 'childSticksToParent', + startBySetting: 'child', + expectedParent: 2, + expectedChild: 2 + }); + }); +}); +/*can-bind@1.1.1#test/detection*/ +define('can-bind@1.1.1#test/detection', [ + 'require', + 'exports', + 'module', + '../can-bind', + 'steal-qunit', + 'can-simple-map', + 'can-simple-observable', + 'can-value' +], function (require, exports, module) { + var Bind = require('../can-bind'); + var QUnit = require('steal-qunit'); + var SimpleMap = require('can-simple-map'); + var SimpleObservable = require('can-simple-observable'); + var value = require('can-value'); + QUnit.module('can-bind binding detection'); + QUnit.test('child-to-parent without child setter', function (assert) { + var parent = new SimpleObservable(undefined); + var map = new SimpleMap({ prop: 'value' }); + var child = value.from(map, 'prop'); + var binding = new Bind({ + child: child, + parent: parent + }); + assert.equal(binding._childToParent, true, 'child -> parent detection'); + assert.equal(binding._parentToChild, false, 'parent -> child detection'); + }); + QUnit.test('child-to-parent without parent getter', function (assert) { + var child = new SimpleObservable(undefined); + var map = new SimpleMap({ prop: 'value' }); + var parent = value.to(map, 'prop'); + var binding = new Bind({ + child: child, + parent: parent + }); + assert.equal(binding._childToParent, true, 'child -> parent detection'); + assert.equal(binding._parentToChild, false, 'parent -> child detection'); + }); + QUnit.test('error thrown for no-way binding', function (assert) { + var child = value.from(new SimpleMap({ prop: 'value' }), 'prop'); + var parent = value.from(new SimpleMap({ prop: 'value' }), 'prop'); + assert.throws(function () { + new Bind({ + child: child, + parent: parent + }); + }, /binding/, 'error thrown'); + }); +}); +/*can-bind@1.1.1#test/initialization*/ +define('can-bind@1.1.1#test/initialization', [ + 'require', + 'exports', + 'module', + '../can-bind', + 'can-reflect', + 'steal-qunit', + 'can-simple-observable/settable/settable', + 'can-simple-observable' +], function (require, exports, module) { + var Bind = require('../can-bind'); + var canReflect = require('can-reflect'); + var QUnit = require('steal-qunit'); + var SettableObservable = require('can-simple-observable/settable/settable'); + var SimpleObservable = require('can-simple-observable'); + QUnit.module('can-bind initialization'); + QUnit.test('undefined child and defined parent with setter', function (assert) { + var child = new SimpleObservable(undefined); + var parentSetterWasCalled = false; + var parent = new SimpleObservable(15); + canReflect.assignSymbols(parent, { + 'can.setValue': function () { + parentSetterWasCalled = true; + } + }); + var binding = new Bind({ + child: child, + parent: parent + }); + binding.start(); + assert.equal(parentSetterWasCalled, false, 'parent setter was not called'); + binding.stop(); + }); + QUnit.test('undefined parent and null child with setter', function (assert) { + var parent = new SimpleObservable(undefined); + var child = new SettableObservable(function (newValue) { + return newValue || ''; + }, null, null); + var binding = new Bind({ + child: child, + cycles: 0, + parent: parent, + sticky: 'childSticksToParent' + }); + binding.start(); + assert.equal(canReflect.getValue(child), '', 'child value is correct'); + binding.stop(); + }); + function initializationTest(options) { + var child = new SimpleObservable(options.startingChild); + var parent = new SimpleObservable(options.startingParent); + var binding = new Bind({ + child: child, + childToParent: options.childToParent, + onInitDoNotUpdateChild: options.onInitDoNotUpdateChild, + onInitSetUndefinedParentIfChildIsDefined: options.onInitSetUndefinedParentIfChildIsDefined, + parent: parent, + parentToChild: options.parentToChild + }); + binding.start(); + QUnit.equal(canReflect.getValue(child), options.expectedChild, 'child value is correct'); + QUnit.equal(canReflect.getValue(parent), options.expectedParent, 'parent value is correct'); + binding.stop(); + } + QUnit.test('child=1 <-> parent=2 => child=2 parent=2', function () { + initializationTest({ + startingChild: 1, + startingParent: 2, + childToParent: true, + parentToChild: true, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 2, + expectedParent: 2 + }); + }); + QUnit.test('child=1 <-> parent=undefined => child=1 parent=1', function () { + initializationTest({ + startingChild: 1, + startingParent: undefined, + childToParent: true, + parentToChild: true, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 1, + expectedParent: 1 + }); + }); + QUnit.test('child=undefined <-> parent=2 => child=2 parent=2', function () { + initializationTest({ + startingChild: undefined, + startingParent: 2, + childToParent: true, + parentToChild: true, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 2, + expectedParent: 2 + }); + }); + QUnit.test('child=undefined <-> parent=undefined => child=undefined parent=undefined', function () { + initializationTest({ + startingChild: undefined, + startingParent: undefined, + childToParent: true, + parentToChild: true, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: undefined, + expectedParent: undefined + }); + }); + QUnit.test('child=3 <-> parent=3 => child=3 parent=3', function () { + initializationTest({ + startingChild: 3, + startingParent: 3, + childToParent: true, + parentToChild: true, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 3, + expectedParent: 3 + }); + }); + QUnit.test('child=1 -> parent=2 => child=1 parent=1', function () { + initializationTest({ + startingChild: 1, + startingParent: 2, + childToParent: true, + parentToChild: false, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 1, + expectedParent: 1 + }); + }); + QUnit.test('child=1 -> parent=undefined => child=1 parent=1', function () { + initializationTest({ + startingChild: 1, + startingParent: undefined, + childToParent: true, + parentToChild: false, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 1, + expectedParent: 1 + }); + }); + QUnit.test('child=undefined -> parent=2 => child=undefined parent=undefined', function () { + initializationTest({ + startingChild: undefined, + startingParent: 2, + childToParent: true, + parentToChild: false, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: undefined, + expectedParent: undefined + }); + }); + QUnit.test('child=undefined -> parent=undefined => child=undefined parent=undefined', function () { + initializationTest({ + startingChild: undefined, + startingParent: undefined, + childToParent: true, + parentToChild: false, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: undefined, + expectedParent: undefined + }); + }); + QUnit.test('child=3 -> parent=3 => child=3 parent=3', function () { + initializationTest({ + startingChild: 3, + startingParent: 3, + childToParent: true, + parentToChild: false, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 3, + expectedParent: 3 + }); + }); + QUnit.test('child=1 <- parent=2 => child=2 parent=2', function () { + initializationTest({ + startingChild: 1, + startingParent: 2, + childToParent: false, + parentToChild: true, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 2, + expectedParent: 2 + }); + }); + QUnit.test('child=1 <- parent=undefined => child=undefined parent=undefined', function () { + initializationTest({ + startingChild: 1, + startingParent: undefined, + childToParent: false, + parentToChild: true, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: undefined, + expectedParent: undefined + }); + }); + QUnit.test('child=undefined <- parent=2 => child=2 parent=2', function () { + initializationTest({ + startingChild: undefined, + startingParent: 2, + childToParent: false, + parentToChild: true, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 2, + expectedParent: 2 + }); + }); + QUnit.test('child=undefined <- parent=undefined => child=undefined parent=undefined', function () { + initializationTest({ + startingChild: undefined, + startingParent: undefined, + childToParent: false, + parentToChild: true, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: undefined, + expectedParent: undefined + }); + }); + QUnit.test('child=3 <- parent=3 => child=3 parent=3', function () { + initializationTest({ + startingChild: 3, + startingParent: 3, + childToParent: false, + parentToChild: true, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 3, + expectedParent: 3 + }); + }); + QUnit.test('child=1 <-> parent=2 => child=1 parent=2 [onInitDoNotUpdateChild=true]', function () { + initializationTest({ + startingChild: 1, + startingParent: 2, + childToParent: true, + parentToChild: true, + onInitDoNotUpdateChild: true, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 1, + expectedParent: 2 + }); + }); + QUnit.test('child=1 <-> parent=undefined => child=1 parent=1 [onInitDoNotUpdateChild=true]', function () { + initializationTest({ + startingChild: 1, + startingParent: undefined, + childToParent: true, + parentToChild: true, + onInitDoNotUpdateChild: true, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 1, + expectedParent: 1 + }); + }); + QUnit.test('child=undefined <-> parent=2 => child=undefined parent=2 [onInitDoNotUpdateChild=true]', function () { + initializationTest({ + startingChild: undefined, + startingParent: 2, + childToParent: true, + parentToChild: true, + onInitDoNotUpdateChild: true, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: undefined, + expectedParent: 2 + }); + }); + QUnit.test('child=undefined <-> parent=undefined => child=undefined parent=undefined [onInitDoNotUpdateChild=true]', function () { + initializationTest({ + startingChild: undefined, + startingParent: undefined, + childToParent: true, + parentToChild: true, + onInitDoNotUpdateChild: true, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: undefined, + expectedParent: undefined + }); + }); + QUnit.test('child=3 <-> parent=3 => child=3 parent=3 [onInitDoNotUpdateChild=true]', function () { + initializationTest({ + startingChild: 3, + startingParent: 3, + childToParent: true, + parentToChild: true, + onInitDoNotUpdateChild: true, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 3, + expectedParent: 3 + }); + }); + QUnit.test('child=1 <- parent=2 => child=1 parent=2 [onInitDoNotUpdateChild=true]', function () { + initializationTest({ + startingChild: 1, + startingParent: 2, + childToParent: false, + parentToChild: true, + onInitDoNotUpdateChild: true, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 1, + expectedParent: 2 + }); + }); + QUnit.test('child=1 <- parent=undefined => child=1 parent=undefined [onInitDoNotUpdateChild=true]', function () { + initializationTest({ + startingChild: 1, + startingParent: undefined, + childToParent: false, + parentToChild: true, + onInitDoNotUpdateChild: true, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 1, + expectedParent: undefined + }); + }); + QUnit.test('child=undefined <- parent=2 => child=undefined parent=2 [onInitDoNotUpdateChild=true]', function () { + initializationTest({ + startingChild: undefined, + startingParent: 2, + childToParent: false, + parentToChild: true, + onInitDoNotUpdateChild: true, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: undefined, + expectedParent: 2 + }); + }); + QUnit.test('child=undefined <- parent=undefined => child=undefined parent=undefined [onInitDoNotUpdateChild=true]', function () { + initializationTest({ + startingChild: undefined, + startingParent: undefined, + childToParent: false, + parentToChild: true, + onInitDoNotUpdateChild: true, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: undefined, + expectedParent: undefined + }); + }); + QUnit.test('child=3 <- parent=3 => child=3 parent=3 [onInitDoNotUpdateChild=true]', function () { + initializationTest({ + startingChild: 3, + startingParent: 3, + childToParent: false, + parentToChild: true, + onInitDoNotUpdateChild: true, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 3, + expectedParent: 3 + }); + }); +}); +/*can-bind@1.1.1#test/test*/ +define('can-bind@1.1.1#test/test', [ + 'require', + 'exports', + 'module', + './core', + './cycles-and-sticky', + './detection', + './initialization' +], function (require, exports, module) { + require('./core'); + require('./cycles-and-sticky'); + require('./detection'); + require('./initialization'); +}); +/*can-construct@3.5.3#can-construct_test*/ +define('can-construct@3.5.3#can-construct_test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-construct', + 'can-log/dev/dev' +], function (require, exports, module) { + (function (global, require, exports, module) { + QUnit = require('steal-qunit'); + var Construct = require('can-construct'); + var dev = require('can-log/dev/dev'); + QUnit.module('can-construct', { + setup: function () { + var Animal = this.Animal = Construct.extend({ + count: 0, + test: function () { + return this.match ? true : false; + } + }, { + init: function () { + this.constructor.count++; + this.eyes = false; + } + }); + var Dog = this.Dog = this.Animal.extend({ match: /abc/ }, { + init: function () { + Animal.prototype.init.apply(this, arguments); + }, + talk: function () { + return 'Woof'; + } + }); + this.Ajax = this.Dog.extend({ count: 0 }, { + init: function (hairs) { + Dog.prototype.init.apply(this, arguments); + this.hairs = hairs; + this.setEyes(); + }, + setEyes: function () { + this.eyes = true; + } + }); + } + }); + test('inherit', function () { + var Base = Construct({}); + ok(new Base() instanceof Construct); + var Inherit = Base({}); + ok(new Inherit() instanceof Base); + }); + test('Creating', function () { + new this.Dog(); + var a1 = new this.Animal(); + new this.Animal(); + var ajax = new this.Ajax(1000); + equal(2, this.Animal.count, 'right number of animals'); + equal(1, this.Dog.count, 'right number of animals'); + ok(this.Dog.match, 'right number of animals'); + ok(!this.Animal.match, 'right number of animals'); + ok(this.Dog.test(), 'right number of animals'); + ok(!this.Animal.test(), 'right number of animals'); + equal(1, this.Ajax.count, 'right number of animals'); + equal(2, this.Animal.count, 'right number of animals'); + equal(true, ajax.eyes, 'right number of animals'); + equal(1000, ajax.hairs, 'right number of animals'); + ok(a1 instanceof this.Animal); + ok(a1 instanceof Construct); + }); + test('new instance', function () { + var d = this.Ajax.newInstance(6); + equal(6, d.hairs); + }); + test('namespaces', function () { + var fb = Construct.extend('Bar'); + ok(!window.Bar, 'not added to global namespace'); + if (Object.getOwnPropertyDescriptor) { + equal(fb.name, 'Bar', 'name is right'); + } + equal(fb.shortName, 'Bar', 'short name is right'); + }); + test('setups', function () { + var order = 0, staticSetup, staticSetupArgs, staticInit, staticInitArgs, protoSetup, protoInitArgs, protoInit, staticProps = { + setup: function () { + staticSetup = ++order; + staticSetupArgs = arguments; + return ['something']; + }, + init: function () { + staticInit = ++order; + staticInitArgs = arguments; + } + }, protoProps = { + setup: function (name) { + protoSetup = ++order; + return ['Ford: ' + name]; + }, + init: function () { + protoInit = ++order; + protoInitArgs = arguments; + } + }; + var Car = Construct.extend('Car', staticProps, protoProps); + new Car('geo'); + equal(staticSetup, 1); + equal(staticInit, 2); + equal(protoSetup, 3); + equal(protoInit, 4); + deepEqual(Array.prototype.slice.call(staticInitArgs), ['something']); + deepEqual(Array.prototype.slice.call(protoInitArgs), ['Ford: geo']); + deepEqual(Array.prototype.slice.call(staticSetupArgs), [ + Construct, + 'Car', + staticProps, + protoProps + ], 'static construct'); + Car.extend('Truck'); + equal(staticSetup, 5, 'Static setup is called if overwriting'); + }); + test('Creating without extend', function () { + var Bar = Construct('Bar', { + ok: function () { + ok(true, 'ok called'); + } + }); + new Bar().ok(); + var Foo = Bar('Foo', { + dude: function () { + ok(true, 'dude called'); + } + }); + new Foo().dude(true); + }); + test('setup called with original arguments', function () { + var o2 = {}; + var o1 = { + setup: function (base, arg1, arg2) { + equal(o1, arg1, 'first argument is correct'); + equal(o2, arg2, 'second argument is correct'); + } + }; + Construct.extend(o1, o2); + }); + test('legacy namespace strings (A.B.C) accepted', function () { + var Type = Construct.extend('Foo.Bar.Baz'); + var expectedValue = ~steal.config('env').indexOf('production') ? '' : 'Foo_Bar_Baz'; + ok(new Type() instanceof Construct, 'No unexpected behavior in the prototype chain'); + if (Function.prototype.name) { + equal(Type.name, expectedValue, 'Name becomes underscored'); + } + }); + test('reserved words accepted', function () { + var Type = Construct.extend('const'); + var expectedValue = ~steal.config('env').indexOf('production') ? '' : 'Const'; + ok(new Type() instanceof Construct, 'No unexpected behavior in the prototype chain'); + if (Function.prototype.name) { + equal(Type.name, expectedValue, 'Name becomes capitalized'); + } + }); + test('basic injection attacks thwarted', function () { + var rootToken = typeof window === 'undefined' ? 'global' : 'window'; + var rootObject = typeof window === 'undefined' ? global : window; + var expando = 'foo' + Math.random().toString(10).slice(2); + var MalignantType; + try { + MalignantType = Construct.extend('(){};' + rootToken + '.' + expando + '=\'bar\';var f=function'); + } catch (e) { + } finally { + equal(rootObject[expando], undefined, 'Injected code doesn\'t run'); + } + delete rootObject[expando]; + try { + MalignantType = Construct.extend('(){},' + rootToken + '.' + expando + '=\'baz\',function'); + } catch (e) { + } finally { + equal(rootObject[expando], undefined, 'Injected code doesn\'t run'); + } + }); + QUnit.test('setters not invoked on extension (#28)', function () { + var extending = true; + var Base = Construct.extend('Base', { + set something(value) { + QUnit.ok(!extending, 'called when not extending'); + }, + get something() { + } + }); + Base.extend('Extended', { something: 'value' }); + extending = false; + new Base().something = 'foo'; + }); + QUnit.test('return alternative value simple', function () { + var Alternative = function () { + }; + var Base = Construct.extend({ + setup: function () { + return new Construct.ReturnValue(new Alternative()); + } + }); + QUnit.ok(new Base() instanceof Alternative, 'Should create an instance of Alternative'); + }); + QUnit.test('return alternative value on setup (full case)', function () { + var Student = function (name, school) { + this.name = name; + this.school = school; + this.isStudent = true; + }; + var Person = Construct.extend({ + setup: function (opts) { + if (opts.age >= 16) { + return new Construct.ReturnValue(new Student(opts.name, opts.school)); + } + opts.isStudent = false; + return [opts]; + }, + init: function (params) { + this.age = params.age; + this.name = params.name; + this.isStudent = params.isStudent; + } + }); + QUnit.equal(new Person({ age: 12 }).isStudent, false, 'Age 12 cannot be a student'); + QUnit.equal(new Person({ age: 30 }).isStudent, true, 'Age 20 can be a student'); + QUnit.ok(new Person({ age: 30 }) instanceof Student, 'Should return an instance of Student'); + }); + QUnit.test('extends defaults right', function () { + var BASE = Construct.extend({ defaults: { foo: 'bar' } }, {}); + var INHERIT = BASE.extend({ defaults: { newProp: 'newVal' } }, {}); + ok(INHERIT.defaults.foo === 'bar', 'Class must inherit defaults from the parent class'); + ok(INHERIT.defaults.newProp === 'newVal', 'Class must have own defaults'); + }); + QUnit.test('enumerability', function () { + var Parent = Construct.extend('Parent', {}); + var child = new Parent(); + child.foo = 'bar'; + var props = {}; + for (var prop in child) { + props[prop] = true; + } + QUnit.deepEqual(props, { foo: true }, 'only has ownProps'); + }); + QUnit.test('Has default init, setup functions', function () { + var instance = new Construct(); + QUnit.equal(typeof instance.init, 'function', 'has init'); + QUnit.equal(typeof instance.setup, 'function', 'has setup'); + }); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-construct-super@3.2.0#can-construct-super*/ +define('can-construct-super@3.2.0#can-construct-super', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-construct' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var Construct = require('can-construct'); + var hasOwnProperty = Object.prototype.hasOwnProperty; + var isFunction = function (val) { + return typeof val === 'function'; + }, fnTest = /xyz/.test(function () { + return this.xyz; + }) ? /\b_super\b/ : /.*/, getset = [ + 'get', + 'set' + ], getSuper = function (base, name, fn) { + return function () { + var hasExistingValue = false; + var existingValue; + var prototype = getPrototypeOf(this); + var existingPrototypeValue = prototype._super; + if (hasOwnProperty.call(this, '_super')) { + hasExistingValue = true; + existingValue = this._super; + delete this._super; + } + prototype._super = base[name]; + var ret = fn.apply(this, arguments); + prototype._super = existingPrototypeValue; + if (hasExistingValue) { + this._super = existingValue; + } + return ret; + }; + }; + Construct._defineProperty = function (addTo, base, name, descriptor) { + var _super = Object.getOwnPropertyDescriptor(base, name); + if (_super) { + canReflect.each(getset, function (method) { + if (isFunction(_super[method]) && isFunction(descriptor[method])) { + descriptor[method] = getSuper(_super, method, descriptor[method]); + } else if (!isFunction(descriptor[method])) { + descriptor[method] = _super[method]; + } + }); + } + Object.defineProperty(addTo, name, descriptor); + }; + var getPrototypeOf = Object.getPrototypeOf || function (obj) { + return obj.__proto__; + }; + var getPropertyDescriptor = Object.getPropertyDescriptor || function (subject, name) { + if (name in subject) { + var pd = Object.getOwnPropertyDescriptor(subject, name); + var proto = getPrototypeOf(subject); + while (pd === undefined && proto !== null) { + pd = Object.getOwnPropertyDescriptor(proto, name); + proto = getPrototypeOf(proto); + } + return pd; + } + }; + Construct._overwrite = function (addTo, base, name, val) { + var baseDescriptor = getPropertyDescriptor(base, name); + var baseValue = baseDescriptor && baseDescriptor.value; + Object.defineProperty(addTo, name, { + value: isFunction(val) && isFunction(baseValue) && fnTest.test(val) ? getSuper(base, name, val) : val, + configurable: true, + enumerable: true, + writable: true + }); + }; + module.exports = Construct; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-construct-super@3.2.0#test/can-construct-super_test*/ +define('can-construct-super@3.2.0#test/can-construct-super_test', [ + 'require', + 'exports', + 'module', + 'can-construct-super', + 'steal-qunit' +], function (require, exports, module) { + (function (global, require, exports, module) { + var Construct = require('can-construct-super'); + var QUnit = require('steal-qunit'); + QUnit.module('can-construct-super'); + test('prototype super', function () { + var A = Construct.extend({ + init: function (arg) { + this.arg = arg + 1; + }, + add: function (num) { + return this.arg + num; + } + }); + var B = A({ + init: function (arg) { + this._super(arg + 2); + }, + add: function (arg) { + return this._super(arg + 1); + } + }); + var b = new B(1); + equal(b.arg, 4); + equal(b.add(2), 7); + }); + test('static super', function () { + var First = Construct.extend({ + raise: function (num) { + return num; + } + }, {}); + var Second = First.extend({ + raise: function (num) { + return this._super(num) * num; + } + }, {}); + equal(Second.raise(2), 4); + }); + test('findAll super', function () { + var Parent = Construct.extend({ + findAll: function () { + equal(this.shortName, 'child'); + return Promise.resolve(); + }, + shortName: 'parent' + }, {}); + var Child = Parent.extend({ + findAll: function () { + return this._super(); + }, + shortName: 'child' + }, {}); + stop(); + expect(1); + Child.findAll({}); + start(); + }); + if (Object.getOwnPropertyDescriptor) { + test('_super supports getters and setters', function () { + var Person = Construct.extend({ + get age() { + return 42; + }, + set name(value) { + this._name = value; + }, + get name() { + return this._name; + } + }); + var OtherPerson = Person.extend({ + get age() { + return this._super() + 8; + }, + set name(value) { + this._super(value + '_super'); + } + }); + var test = new OtherPerson(); + test.base = 2; + equal(test.age, 50, 'Getter and _super works'); + test.name = 'David'; + equal(test.name, 'David_super', 'Setter ran'); + }); + } + QUnit.test('setters not invoked on extension (#9)', function () { + var extending = true; + var Base = Construct.extend('Base', { + set something(value) { + QUnit.ok(!extending, 'set not called when not extending'); + }, + get something() { + QUnit.ok(!extending, 'get not called when not extending'); + } + }); + Base.extend('Extended', { something: 'value' }); + extending = false; + new Base().something = 'foo'; + }); + QUnit.test('_super isn\'t always available (#11)', function () { + var Parent = Construct.extend({}); + var Child = Parent.extend({ + init: function () { + this._super(); + ok(true); + } + }); + new Child(); + }); + QUnit.test('_super should work for sealed instances', function () { + var A = Construct.extend({ + init: function (arg) { + this.arg = arg + 1; + }, + add: function (num) { + return this.arg + num; + } + }); + var B = A({ + init: function (arg) { + this._super(arg + 2); + }, + add: function (arg) { + return this._super(arg + 1); + } + }); + var b = new B(1); + Object.seal(b); + equal(b.arg, 4, 'should instantiate properly'); + equal(b.add(2), 7, 'should call methods properly'); + }); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-util@3.14.0#dom/child-nodes/child-nodes*/ +define('can-util@3.14.0#dom/child-nodes/child-nodes', [ + 'require', + 'exports', + 'module', + 'can-namespace' +], function (require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + function childNodes(node) { + var childNodes = node.childNodes; + if ('length' in childNodes) { + return childNodes; + } else { + var cur = node.firstChild; + var nodes = []; + while (cur) { + nodes.push(cur); + cur = cur.nextSibling; + } + return nodes; + } + } + module.exports = namespace.childNodes = childNodes; +}); +/*can-util@3.14.0#dom/fragment/fragment*/ +define('can-util@3.14.0#dom/fragment/fragment', [ + 'require', + 'exports', + 'module', + 'can-globals/document/document', + '../child-nodes/child-nodes', + 'can-namespace' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var getDocument = require('can-globals/document/document'); + var childNodes = require('../child-nodes/child-nodes'); + var namespace = require('can-namespace'); + var fragmentRE = /^\s*<(\w+)[^>]*>/, toString = {}.toString, fragment = function (html, name, doc) { + if (name === undefined) { + name = fragmentRE.test(html) && RegExp.$1; + } + if (html && toString.call(html.replace) === '[object Function]') { + html = html.replace(/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, '<$1>'); + } + var container = doc.createElement('div'), temp = doc.createElement('div'); + if (name === 'tbody' || name === 'tfoot' || name === 'thead' || name === 'colgroup') { + temp.innerHTML = '' + html + '
      '; + container = temp.firstChild.nodeType === 3 ? temp.lastChild : temp.firstChild; + } else if (name === 'col') { + temp.innerHTML = '' + html + '
      '; + container = temp.firstChild.nodeType === 3 ? temp.lastChild : temp.firstChild.firstChild; + } else if (name === 'tr') { + temp.innerHTML = '' + html + '
      '; + container = temp.firstChild.nodeType === 3 ? temp.lastChild : temp.firstChild.firstChild; + } else if (name === 'td' || name === 'th') { + temp.innerHTML = '' + html + '
      '; + container = temp.firstChild.nodeType === 3 ? temp.lastChild : temp.firstChild.firstChild.firstChild; + } else if (name === 'option') { + temp.innerHTML = ''; + container = temp.firstChild.nodeType === 3 ? temp.lastChild : temp.firstChild; + } else { + container.innerHTML = '' + html; + } + var tmp = {}, children = childNodes(container); + tmp.length = children.length; + for (var i = 0; i < children.length; i++) { + tmp[i] = children[i]; + } + return [].slice.call(tmp); + }; + var buildFragment = function (html, doc) { + if (html && html.nodeType === 11) { + return html; + } + if (!doc) { + doc = getDocument(); + } else if (doc.length) { + doc = doc[0]; + } + var parts = fragment(html, undefined, doc), frag = (doc || document).createDocumentFragment(); + for (var i = 0, length = parts.length; i < length; i++) { + frag.appendChild(parts[i]); + } + return frag; + }; + module.exports = namespace.fragment = buildFragment; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-control@4.4.1#can-control_test*/ +define('can-control@4.4.1#can-control_test', [ + 'require', + 'exports', + 'module', + 'can-control', + 'steal-qunit', + 'can-util/dom/fragment/fragment', + 'can-log/dev/dev', + 'can-dom-events', + 'can-dom-mutate', + 'can-dom-mutate/node', + 'can-globals', + 'can-simple-map', + 'can-define/map/', + 'can-simple-observable', + 'can-symbol' +], function (require, exports, module) { + (function (global, require, exports, module) { + var Control = require('can-control'); + var QUnit = require('steal-qunit'); + var fragment = require('can-util/dom/fragment/fragment'); + var dev = require('can-log/dev/dev'); + var domEvents = require('can-dom-events'); + var domMutate = require('can-dom-mutate'); + var domMutateNode = require('can-dom-mutate/node'); + var globals = require('can-globals'); + var SimpleMap = require('can-simple-map'); + var DefineMap = require('can-define/map/'); + var SimpleObservable = require('can-simple-observable'); + var canSymbol = require('can-symbol'); + QUnit.module('can-control', { + setup: function () { + this.fixture = document.getElementById('qunit-fixture'); + } + }); + test('parameterized actions', function () { + var called = false, WeirderBind = Control.extend({ + '{parameterized}': function () { + called = true; + } + }), a; + this.fixture.appendChild(fragment('
      ')); + a = document.getElementById('crazy'); + new WeirderBind(a, { parameterized: 'sillyEvent' }); + domEvents.dispatch(a, 'sillyEvent'); + ok(called, 'heard the trigger'); + }); + test('windowresize', function () { + var called = false, WindowBind = Control.extend('', { + '{window} resize': function () { + called = true; + } + }); + this.fixture.appendChild(fragment('
      ')); + new WindowBind('#weird'); + domEvents.dispatch(window, 'resize'); + ok(called, 'got window resize event'); + }); + test('on', 9, function () { + var called = false, DelegateTest = Control.extend({ + click: function () { + } + }), Tester = Control.extend({ + init: function (el, ops) { + this.on(window, 'click', function (ev) { + ok(true, 'Got window click event'); + }); + this.on(window, 'click', 'clicked'); + this.on('click', function () { + ok(true, 'Directly clicked element'); + }); + this.on('click', 'clicked'); + }, + clicked: function (context) { + ok(true, 'Controller action delegated click triggered, too'); + } + }), div = document.createElement('div'); + this.fixture.appendChild(div); + var rb = new Tester(div); + this.fixture.appendChild(fragment('')); + var dt = new DelegateTest('#els'); + dt.on(document.querySelector('#els span'), 'a', 'click', function () { + called = true; + }); + domEvents.dispatch(document.querySelector('#els a'), 'click'); + ok(called, 'delegate works'); + domMutateNode.removeChild.call(this.fixture, document.querySelector('#els')); + domEvents.dispatch(div, 'click'); + domEvents.dispatch(window, 'click'); + rb.destroy(); + }); + test('inherit', function () { + var called = false, Parent = Control.extend({ + click: function () { + called = true; + } + }), Child = Parent.extend({}); + this.fixture.appendChild(fragment('')); + new Child('#els'); + domEvents.dispatch(document.querySelector('#els'), 'click'); + ok(called, 'inherited the click method'); + }); + test('space makes event', 1, function () { + var Dot = Control.extend({ + ' foo': function () { + ok(true, 'called'); + } + }); + this.fixture.appendChild(fragment('')); + new Dot('#els'); + domEvents.dispatch(document.querySelector('#els'), 'foo'); + }); + test('custom events with hyphens work', 1, function () { + this.fixture.appendChild(fragment('
      ')); + var FooBar = Control.extend({ + 'span custom-event': function () { + ok(true, 'Custom event was fired.'); + } + }); + new FooBar('#customEvent'); + domEvents.dispatch(document.querySelector('#customEvent span'), 'custom-event'); + }); + test('inherit defaults', function () { + var BASE = Control.extend({ defaults: { foo: 'bar' } }, {}); + var INHERIT = BASE.extend({ defaults: { newProp: 'newVal' } }, {}); + ok(INHERIT.defaults.foo === 'bar', 'Class must inherit defaults from the parent class'); + ok(INHERIT.defaults.newProp === 'newVal', 'Class must have own defaults'); + var inst = new INHERIT(document.createElement('div'), {}); + ok(inst.options.foo === 'bar', 'Instance must inherit defaults from the parent class'); + ok(inst.options.newProp === 'newVal', 'Instance must have defaults of it`s class'); + }); + test('on rebinding', 2, function () { + var first = true; + var Rebinder = Control.extend({ + '{item} foo': function (item, ev) { + if (first) { + equal(item.get('id'), 1, 'first item'); + first = false; + } else { + equal(item.get('id'), 2, 'first item'); + } + } + }); + var item1 = new SimpleMap({ id: 1 }), item2 = new SimpleMap({ id: 2 }), rb = new Rebinder(document.createElement('div'), { item: item1 }); + item1.dispatch('foo'); + rb.options = { item: item2 }; + rb.on(); + item2.dispatch('foo'); + }); + test('actions provide method names', function () { + var item1 = new SimpleMap({}); + var item2 = new SimpleMap({}); + var Tester = Control.extend({ + '{item1} foo': 'food', + '{item2} bar': 'food', + food: function (item, ev, data) { + ok(true, 'food called'); + ok(item === item1 || item === item2, 'called with an item'); + } + }); + new Tester(document.createElement('div'), { + item1: item1, + item2: item2 + }); + item1.dispatch('foo'); + item2.dispatch('bar'); + }); + test('Don\'t bind if there are undefined values in templates', function () { + var C = Control.extend({}, { + '{noExistStuff} proc': function () { + } + }); + var c = new C(document.createElement('div')); + equal(c._bindings.user.length, 1, 'There is only one binding'); + var C2 = Control.extend({ + '{noExistStuff} click': function () { + ok(false, 'should not fall through to click handler'); + } + }); + var div = document.createElement('div'); + new C2(div, {}); + domEvents.dispatch(div, 'click'); + }); + test('Multiple calls to destroy', 2, function () { + var C = Control.extend({ + destroy: function () { + ok(true); + Control.prototype.destroy.call(this); + } + }), div = document.createElement('div'), c = new C(div); + c.destroy(); + c.destroy(); + }); + test('drag and drop events', function () { + expect(7); + var DragDrop = Control.extend('', { + ' dragstart': function () { + ok(true, 'dragstart called'); + }, + ' dragenter': function () { + ok(true, 'dragenter called'); + }, + ' dragover': function () { + ok(true, 'dragover called'); + }, + ' dragleave': function () { + ok(true, 'dragleave called'); + }, + ' drag': function () { + ok(true, 'drag called'); + }, + ' drop': function () { + ok(true, 'drop called'); + }, + ' dragend': function () { + ok(true, 'dragend called'); + } + }); + this.fixture.appendChild(fragment('
      ')); + new DragDrop('#draggable'); + var draggable = document.getElementById('draggable'); + domEvents.dispatch(draggable, 'dragstart'); + domEvents.dispatch(draggable, 'dragenter'); + domEvents.dispatch(draggable, 'dragover'); + domEvents.dispatch(draggable, 'dragleave'); + domEvents.dispatch(draggable, 'drag'); + domEvents.dispatch(draggable, 'drop'); + domEvents.dispatch(draggable, 'dragend'); + }); + test('beforeremove event', function () { + expect(1); + var Foo = Control.extend('', { + 'beforeremove': function () { + ok(true, 'beforeremove called'); + } + }); + var el = fragment('
      '); + new Foo(el); + domEvents.dispatch(el, 'beforeremove'); + }); + if (System.env.indexOf('production') < 0) { + test('Control is logging information in dev mode', function () { + expect(2); + var oldlog = dev.log; + var oldwarn = dev.warn; + dev.log = function (text) { + equal(text, 'can-control: No property found for handling {dummy} change', 'Text logged as expected'); + }; + var C = Control.extend({ + '{dummy} change': function () { + } + }); + var instance = new C(document.createElement('div')); + dev.warn = function (text) { + equal(text, 'can-control: Control already destroyed', 'control destroyed warning'); + }; + instance.destroy(); + instance.destroy(); + dev.warn = oldwarn; + dev.log = oldlog; + }); + } + test('event handlers should rebind when target is replaced', function () { + var nameChanges = 0; + var MyControl = Control.extend('MyControl', { + '{person.name} first': function () { + nameChanges++; + }, + name: function (name) { + this.options.person.set('name', name); + } + }); + var c = new MyControl(document.createElement('div'), { person: new SimpleMap({ name: new SimpleMap({ first: 'Kevin' }) }) }); + c.options.person.get('name').set('first', 'Tracy'); + c.name(new SimpleMap({ first: 'Kim' })); + c.options.person.get('name').get('first', 'Max'); + equal(nameChanges, 2); + }); + test('{element} event handling', function () { + expect(3); + stop(); + var MyControl = Control.extend({ + '{element} click': function (element) { + if (element === this.element) { + ok(true, '`{element} click` should catch clicking on the element'); + } else { + ok(true, '`{element} click` should catch clicking on a child of the element'); + } + }, + '{element} p click': function () { + ok(true, '`{element} p click` works'); + start(); + } + }); + var div = document.createElement('div'); + var p = document.createElement('p'); + div.appendChild(p); + new MyControl(div, { foo: 'bar' }); + domEvents.dispatch(div, 'click'); + domEvents.dispatch(p, 'click'); + }); + test('Passing a Map as options works', function () { + expect(2); + stop(); + var MyControl = Control.extend({ defaults: { testEndEvent: 'mouseleave' } }, { + '{element} {eventType}': function () { + ok(true, 'catches handler from options'); + }, + '{element} {testEndEvent}': function () { + ok(true, 'catches handler from defaults'); + start(); + } + }); + var map = new SimpleMap({ eventType: 'click' }); + var div = document.createElement('div'); + new MyControl(div, map); + map.attr('eventType', 'mouseenter'); + domEvents.dispatch(div, 'mouseenter'); + domEvents.dispatch(div, 'mouseleave'); + }); + test('Passing a DefineMap as options works', function () { + expect(2); + stop(); + var MyControl = Control.extend({ defaults: { testEndEvent: 'mouseleave' } }, { + '{element} {eventType}': function () { + ok(true, 'catches handler from options'); + }, + '{element} {testEndEvent}': function () { + ok(true, 'catches handler from defaults'); + start(); + } + }); + var MyMap = DefineMap.extend({ + eventType: 'string', + testEndEvent: 'string' + }); + var map = new MyMap(); + map.eventType = 'click'; + var div = document.createElement('div'); + new MyControl(div, map); + map.eventType = 'mousenter'; + domEvents.dispatch(div, 'mousenter'); + domEvents.dispatch(div, 'mouseleave'); + }); + test('Creating an instance of a named control without passing an element', function () { + var MyControl = Control.extend('MyControl'); + try { + new MyControl(); + } catch (e) { + ok(true, 'Caught an exception'); + } + }); + test('Creating an instance of a named control passing a selector', function () { + this.fixture.appendChild(fragment('
      d
      ')); + var MyControl = Control.extend('MyControl'); + var myControlInstance = new MyControl('#my-control'); + ok(myControlInstance.element.classList.contains('MyControl'), 'Element has the correct class name'); + }); + QUnit.test('can watch SimpleObservable', function () { + var MyControl = Control.extend({ + '{simple}': function (simple, newVal) { + QUnit.equal(newVal, 6); + } + }); + var div = document.createElement('div'); + var simple = new SimpleObservable(5); + new MyControl(div, { simple: simple }); + simple.set(6); + }); + QUnit.test('get controls using a symbol (#128)', function () { + var MyControl = Control.extend({}); + var div = document.createElement('div'); + var instance = new MyControl(div, {}); + QUnit.deepEqual(div[canSymbol.for('can.controls')], [instance], 'right instance'); + }); + QUnit.test('Able to handle the documentElement being removed', function () { + var doc = document.implementation.createHTMLDocument('Test'); + var div = doc.createElement('div'); + doc.body.appendChild(div); + new Control(div, {}); + globals.setKeyValue('document', doc); + var teardown = domMutate.onNodeRemoval(div, function () { + teardown(); + globals.setKeyValue('document', document); + QUnit.ok(true, 'it worked'); + start(); + }); + doc.removeChild(doc.documentElement); + stop(); + }); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-define-lazy-value@1.1.0#define-lazy-value-test*/ +define('can-define-lazy-value@1.1.0#define-lazy-value-test', [ + 'steal-qunit@1.0.2#steal-qunit', + 'can-define-lazy-value@1.1.0#define-lazy-value' +], function (_stealQunit, _canDefineLazyValue) { + 'use strict'; + var _stealQunit2 = _interopRequireDefault(_stealQunit); + var _canDefineLazyValue2 = _interopRequireDefault(_canDefineLazyValue); + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj }; + } + _stealQunit2.default.module('can-define-lazy-value'); + _stealQunit2.default.test('docs', function () { + var _id = 1; + function getId() { + return _id++; + } + function MyObj(name) { + this.name = name; + } + (0, _canDefineLazyValue2.default)(MyObj.prototype, 'id', getId); + var obj1 = new MyObj('obj1'); + var obj2 = new MyObj('obj2'); + _stealQunit2.default.equal(obj2.id, 1, 'first object read should get id 1'); + _stealQunit2.default.equal(obj1.id, 2, 'second object read should get id 2'); + try { + obj1.id = 3; + } catch (e) { + _stealQunit2.default.ok(true, 'obj1.id should not be writable by default'); + } + (0, _canDefineLazyValue2.default)(MyObj.prototype, 'id', getId, true); + var obj3 = new MyObj('obj3'); + _stealQunit2.default.equal(obj3.id, 3, 'obj3 should have id'); + obj3.id = 4; + _stealQunit2.default.equal(obj3.id, 4, 'obj3.id should be writeable'); + }); +}); +/*can-deparam@1.2.0#can-deparam*/ +define('can-deparam@1.2.0#can-deparam', [ + 'require', + 'exports', + 'module', + 'can-namespace' +], function (require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + var digitTest = /^\d+$/, keyBreaker = /([^\[\]]+)|(\[\])/g, paramTest = /([^?#]*)(#.*)?$/, entityRegex = /%([^0-9a-f][0-9a-f]|[0-9a-f][^0-9a-f]|[^0-9a-f][^0-9a-f])/i, prep = function (str) { + str = str.replace(/\+/g, ' '); + try { + return decodeURIComponent(str); + } catch (e) { + return decodeURIComponent(str.replace(entityRegex, function (match, hex) { + return '%25' + hex; + })); + } + }; + function isArrayLikeName(name) { + return digitTest.test(name) || name === '[]'; + } + function idenity(value) { + return value; + } + module.exports = namespace.deparam = function (params, valueDeserializer) { + valueDeserializer = valueDeserializer || idenity; + var data = {}, pairs, lastPart; + if (params && paramTest.test(params)) { + pairs = params.split('&'); + pairs.forEach(function (pair) { + var parts = pair.split('='), key = prep(parts.shift()), value = prep(parts.join('=')), current = data; + if (key) { + parts = key.match(keyBreaker); + for (var j = 0, l = parts.length - 1; j < l; j++) { + var currentName = parts[j], nextName = parts[j + 1], currentIsArray = isArrayLikeName(currentName) && current instanceof Array; + if (!current[currentName]) { + if (currentIsArray) { + current.push(isArrayLikeName(nextName) ? [] : {}); + } else { + current[currentName] = isArrayLikeName(nextName) ? [] : {}; + } + } + if (currentIsArray) { + current = current[current.length - 1]; + } else { + current = current[currentName]; + } + } + lastPart = parts.pop(); + if (isArrayLikeName(lastPart)) { + current.push(valueDeserializer(value)); + } else { + current[lastPart] = valueDeserializer(value); + } + } + }); + } + return data; + }; +}); +/*can-deparam@1.2.0#can-deparam-test*/ +define('can-deparam@1.2.0#can-deparam-test', [ + 'require', + 'exports', + 'module', + './can-deparam', + 'steal-qunit', + 'can-string-to-any' +], function (require, exports, module) { + var deparam = require('./can-deparam'); + var QUnit = require('steal-qunit'); + var stringToAny = require('can-string-to-any'); + QUnit.module('can-deparam'); + test('Nested deparam', function () { + var data = deparam('a[b]=1&a[c]=2'); + equal(data.a.b, 1); + equal(data.a.c, 2); + data = deparam('a[]=1&a[]=2'); + equal(data.a[0], 1); + equal(data.a[1], 2); + data = deparam('a[b][]=1&a[b][]=2'); + equal(data.a.b[0], 1); + equal(data.a.b[1], 2); + data = deparam('a[0]=1&a[1]=2'); + equal(data.a[0], 1); + equal(data.a[1], 2); + }); + test('Remaining ampersand', function () { + var data = deparam('a[b]=1&a[c]=2&'); + deepEqual(data, { + a: { + b: '1', + c: '2' + } + }); + }); + test('Invalid encoding', function () { + var data = deparam('foo=%0g'); + deepEqual(data, { foo: '%0g' }); + }); + QUnit.test('deparam deep', function () { + QUnit.deepEqual(deparam('age[or][][lte]=5&age[or][]=null'), { + age: { + or: [ + { lte: '5' }, + 'null' + ] + } + }); + }); + QUnit.test('takes value deserializer', function () { + QUnit.deepEqual(deparam('age[or][][lte]=5&age[or][]=null', stringToAny), { + age: { + or: [ + { lte: 5 }, + null + ] + } + }); + QUnit.deepEqual(deparam('undefined=undefined&null=null&NaN=NaN&true=true&false=false', stringToAny), { + 'undefined': undefined, + 'null': null, + 'NaN': NaN, + 'true': true, + 'false': false + }); + }); +}); +/*can-dom-events@1.3.3#helpers/make-event-registry-test*/ +define('can-dom-events@1.3.3#helpers/make-event-registry-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './make-event-registry' +], function (require, exports, module) { + var unit = require('steal-qunit'); + var makeEventRegistry = require('./make-event-registry'); + unit.module('make-event-registry'); + unit.test('add should register the event with the given eventType', function (assert) { + var eventType = 'boi'; + var registry = makeEventRegistry(); + var exampleEvent = { + defaultEventType: 'cake', + addEventListener: function () { + }, + removeEventListener: function () { + } + }; + registry.add(exampleEvent, eventType); + assert.equal(registry.has(eventType), true, 'event should be registered at "' + eventType + '"'); + }); + unit.test('add should use the event\'s defaultEventType unless eventType is provided', function (assert) { + var eventType = 'boi'; + var registry = makeEventRegistry(); + var exampleEvent = { + defaultEventType: eventType, + addEventListener: function () { + }, + removeEventListener: function () { + } + }; + registry.add(exampleEvent); + assert.equal(registry.has(eventType), true, 'event should be registered at "' + eventType + '"'); + }); + unit.test('has should return whether an event is registered', function (assert) { + var eventType = 'boi'; + var exampleEvent = { + defaultEventType: eventType, + addEventListener: function () { + }, + removeEventListener: function () { + } + }; + var registry = makeEventRegistry(); + assert.equal(registry.has(eventType), false, 'initial registry should not have the event'); + var remove = registry.add(exampleEvent); + assert.equal(registry.has(eventType), true, 'updated registry should have the event'); + remove(); + assert.equal(registry.has(eventType), false, 'empty registry should not have the event'); + }); + unit.test('get should return the register event', function (assert) { + var eventType = 'boi'; + var exampleEvent = { + defaultEventType: eventType, + addEventListener: function () { + }, + removeEventListener: function () { + } + }; + var registry = makeEventRegistry(); + assert.equal(registry.get(eventType), undefined, 'initial registry should not have the event'); + var remove = registry.add(exampleEvent); + assert.equal(registry.get(eventType), exampleEvent, 'updated registry should have the event'); + remove(); + assert.equal(registry.get(eventType), undefined, 'empty registry should not have the event'); + }); +}); +/*can-dom-events@1.3.3#helpers/add-event-compat*/ +define('can-dom-events@1.3.3#helpers/add-event-compat', [ + 'require', + 'exports', + 'module', + './util' +], function (require, exports, module) { + 'use strict'; + var util = require('./util'); + var addDomContext = util.addDomContext; + var removeDomContext = util.removeDomContext; + function isDomEvents(obj) { + return !!(obj && obj.addEventListener && obj.removeEventListener && obj.dispatch); + } + function isNewEvents(obj) { + return typeof obj.addEvent === 'function'; + } + module.exports = function addEventCompat(domEvents, customEvent, customEventType) { + if (!isDomEvents(domEvents)) { + throw new Error('addEventCompat() must be passed can-dom-events or can-util/dom/events/events'); + } + customEventType = customEventType || customEvent.defaultEventType; + if (isNewEvents(domEvents)) { + return domEvents.addEvent(customEvent, customEventType); + } + var registry = domEvents._compatRegistry; + if (!registry) { + registry = domEvents._compatRegistry = {}; + } + if (registry[customEventType]) { + return function noopRemoveOverride() { + }; + } + registry[customEventType] = customEvent; + var newEvents = { + addEventListener: function () { + var data = removeDomContext(this, arguments); + return domEvents.addEventListener.apply(data.context, data.args); + }, + removeEventListener: function () { + var data = removeDomContext(this, arguments); + return domEvents.removeEventListener.apply(data.context, data.args); + }, + dispatch: function () { + var data = removeDomContext(this, arguments); + var eventData = data.args[0]; + var eventArgs = typeof eventData === 'object' ? eventData.args : []; + data.args.splice(1, 0, eventArgs); + return domEvents.dispatch.apply(data.context, data.args); + } + }; + var isOverriding = true; + var oldAddEventListener = domEvents.addEventListener; + var addEventListener = domEvents.addEventListener = function addEventListener(eventName) { + if (isOverriding && eventName === customEventType) { + var args = addDomContext(this, arguments); + customEvent.addEventListener.apply(newEvents, args); + } + return oldAddEventListener.apply(this, arguments); + }; + var oldRemoveEventListener = domEvents.removeEventListener; + var removeEventListener = domEvents.removeEventListener = function removeEventListener(eventName) { + if (isOverriding && eventName === customEventType) { + var args = addDomContext(this, arguments); + customEvent.removeEventListener.apply(newEvents, args); + } + return oldRemoveEventListener.apply(this, arguments); + }; + return function removeOverride() { + isOverriding = false; + registry[customEventType] = null; + if (domEvents.addEventListener === addEventListener) { + domEvents.addEventListener = oldAddEventListener; + } + if (domEvents.removeEventListener === removeEventListener) { + domEvents.removeEventListener = oldRemoveEventListener; + } + }; + }; +}); +/*can-dom-events@1.3.3#helpers/add-event-compat-test*/ +define('can-dom-events@1.3.3#helpers/add-event-compat-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './add-event-compat', + '../can-dom-events' +], function (require, exports, module) { + var unit = require('steal-qunit'); + var addEvent = require('./add-event-compat'); + var domEvents = require('../can-dom-events'); + var oldDomEventsMock = function (addSpy, removeSpy) { + return { + addEventListener: function () { + addSpy(this, arguments); + this.addEventListener.apply(this, arguments); + }, + removeEventListener: function () { + removeSpy(this, arguments); + this.removeEventListener.apply(this, arguments); + }, + dispatch: function () { + } + }; + }; + unit.module('add-event-compat'); + var mockEvent = function (addSpy, removeSpy) { + return { + defaultEventType: 'boi', + addEventListener: function (target, eventName, handler) { + addSpy(this, arguments); + this.addEventListener(target, 'boi2', handler); + }, + removeEventListener: function (target, eventName, handler) { + removeSpy(this, arguments); + this.removeEventListener(target, 'boi2', handler); + } + }; + }; + unit.test('should work with the can-dom-events', function (assert) { + assert.expect(1 + 2 * 4); + var input = document.createElement('input'); + var handler = function () { + assert.ok(true, 'handler should be called'); + }; + var customEventType = 'boi3'; + var hookSpy = function (context, args) { + assert.equal(context, domEvents, 'real domEvents should be context'); + var target = args[0]; + var eventType = args[1]; + var callback = args[2]; + assert.equal(target, input, 'input should be the target'); + assert.equal(eventType, customEventType, 'event type should match custom event type'); + assert.equal(callback, handler, 'callback should be the passed handler'); + }; + var event = mockEvent(hookSpy, hookSpy); + var removeEvent = addEvent(domEvents, event, customEventType); + domEvents.addEventListener(input, customEventType, handler); + domEvents.dispatch(input, 'boi2'); + domEvents.removeEventListener(input, customEventType, handler); + removeEvent(); + }); + unit.test('should work with the can-dom-events (no custom event type)', function (assert) { + assert.expect(1 + 2 * 4); + var input = document.createElement('input'); + var handler = function () { + assert.ok(true, 'handler should be called'); + }; + var customEventType = 'boi'; + var hookSpy = function (context, args) { + assert.equal(context, domEvents, 'real domEvents should be context'); + var target = args[0]; + var eventType = args[1]; + var callback = args[2]; + assert.equal(target, input, 'input should be the target'); + assert.equal(eventType, customEventType, 'event type should match custom event type'); + assert.equal(callback, handler, 'callback should be the passed handler'); + }; + var event = mockEvent(hookSpy, hookSpy); + var removeEvent = addEvent(domEvents, event); + domEvents.addEventListener(input, customEventType, handler); + domEvents.dispatch(input, 'boi2'); + domEvents.removeEventListener(input, customEventType, handler); + removeEvent(); + }); + unit.test('should work with the can-util/dom/events', function (assert) { + assert.expect(1 + 2 * (2 + 3)); + var input = document.createElement('input'); + var handler = function () { + assert.ok(true, 'handler should be called'); + }; + var customEventType = 'boi3'; + var eventsSpy = function (context, args) { + var target = context; + var eventType = args[0]; + var callback = args[1]; + if (eventType === customEventType) { + assert.equal(target, input, 'input should be the target'); + assert.equal(callback, handler, 'callback should be the passed handler'); + } + }; + var oldEvents = oldDomEventsMock(eventsSpy, eventsSpy); + var hookSpy = function (context, args) { + var target = args[0]; + var eventType = args[1]; + var callback = args[2]; + assert.equal(target, input, 'input should be the target'); + assert.equal(eventType, customEventType, 'event type should match custom event type'); + assert.equal(callback, handler, 'callback should be the passed handler'); + }; + var event = mockEvent(hookSpy, hookSpy); + var removeEvent = addEvent(oldEvents, event, customEventType); + oldEvents.addEventListener.call(input, customEventType, handler); + domEvents.dispatch(input, 'boi2'); + oldEvents.removeEventListener.call(input, customEventType, handler); + removeEvent(); + }); + unit.test('should work with the can-util/dom/events (no custom event type)', function (assert) { + assert.expect(1 + 2 * (2 + 3)); + var input = document.createElement('input'); + var handler = function () { + assert.ok(true, 'handler should be called'); + }; + var customEventType = 'boi'; + var eventsSpy = function (context, args) { + var target = context; + var eventType = args[0]; + var callback = args[1]; + if (eventType === customEventType) { + assert.equal(target, input, 'input should be the target'); + assert.equal(callback, handler, 'callback should be the passed handler'); + } + }; + var oldEvents = oldDomEventsMock(eventsSpy, eventsSpy); + var hookSpy = function (context, args) { + var target = args[0]; + var eventType = args[1]; + var callback = args[2]; + assert.equal(target, input, 'input should be the target'); + assert.equal(eventType, customEventType, 'event type should match custom event type'); + assert.equal(callback, handler, 'callback should be the passed handler'); + }; + var event = mockEvent(hookSpy, hookSpy); + var removeEvent = addEvent(oldEvents, event); + oldEvents.addEventListener.call(input, customEventType, handler); + domEvents.dispatch(input, 'boi2'); + oldEvents.removeEventListener.call(input, customEventType, handler); + removeEvent(); + }); + unit.test('should not override can-util/dom/events twice for the same eventType', function (assert) { + var done = assert.async(); + var input = document.createElement('input'); + var event = { + addEventListener: function (target, eventType, handler) { + target.addEventListener(eventType, handler); + }, + removeEventListener: function (target, eventType, handler) { + target.removeEventListener(eventType, handler); + } + }; + var eventsSpy = function () { + }; + var oldEvents = oldDomEventsMock(eventsSpy, eventsSpy); + var removeEvent1 = addEvent(oldEvents, event, 'foo'); + var removeEvent2 = addEvent(oldEvents, event, 'foo'); + var handler = function () { + removeEvent1(); + removeEvent2(); + assert.ok(true, 'This handler should only be called once'); + done(); + }; + oldEvents.addEventListener.call(input, 'foo', handler); + domEvents.dispatch(input, 'foo'); + oldEvents.removeEventListener.call(input, 'foo', handler); + }); +}); +/*jquery@3.3.1#dist/jquery*/ +(function (global, factory) { + 'use strict'; + if (typeof module === 'object' && typeof module.exports === 'object') { + module.exports = global.document ? factory(global, true) : function (w) { + if (!w.document) { + throw new Error('jQuery requires a window with a document'); + } + return factory(w); + }; + } else { + factory(global); + } +}(typeof window !== 'undefined' ? window : this, function (window, noGlobal) { + 'use strict'; + var arr = []; + var document = window.document; + var getProto = Object.getPrototypeOf; + var slice = arr.slice; + var concat = arr.concat; + var push = arr.push; + var indexOf = arr.indexOf; + var class2type = {}; + var toString = class2type.toString; + var hasOwn = class2type.hasOwnProperty; + var fnToString = hasOwn.toString; + var ObjectFunctionString = fnToString.call(Object); + var support = {}; + var isFunction = function isFunction(obj) { + return typeof obj === 'function' && typeof obj.nodeType !== 'number'; + }; + var isWindow = function isWindow(obj) { + return obj != null && obj === obj.window; + }; + var preservedScriptAttributes = { + type: true, + src: true, + noModule: true + }; + function DOMEval(code, doc, node) { + doc = doc || document; + var i, script = doc.createElement('script'); + script.text = code; + if (node) { + for (i in preservedScriptAttributes) { + if (node[i]) { + script[i] = node[i]; + } + } + } + doc.head.appendChild(script).parentNode.removeChild(script); + } + function toType(obj) { + if (obj == null) { + return obj + ''; + } + return typeof obj === 'object' || typeof obj === 'function' ? class2type[toString.call(obj)] || 'object' : typeof obj; + } + var version = '3.3.1', jQuery = function (selector, context) { + return new jQuery.fn.init(selector, context); + }, rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; + jQuery.fn = jQuery.prototype = { + jquery: version, + constructor: jQuery, + length: 0, + toArray: function () { + return slice.call(this); + }, + get: function (num) { + if (num == null) { + return slice.call(this); + } + return num < 0 ? this[num + this.length] : this[num]; + }, + pushStack: function (elems) { + var ret = jQuery.merge(this.constructor(), elems); + ret.prevObject = this; + return ret; + }, + each: function (callback) { + return jQuery.each(this, callback); + }, + map: function (callback) { + return this.pushStack(jQuery.map(this, function (elem, i) { + return callback.call(elem, i, elem); + })); + }, + slice: function () { + return this.pushStack(slice.apply(this, arguments)); + }, + first: function () { + return this.eq(0); + }, + last: function () { + return this.eq(-1); + }, + eq: function (i) { + var len = this.length, j = +i + (i < 0 ? len : 0); + return this.pushStack(j >= 0 && j < len ? [this[j]] : []); + }, + end: function () { + return this.prevObject || this.constructor(); + }, + push: push, + sort: arr.sort, + splice: arr.splice + }; + jQuery.extend = jQuery.fn.extend = function () { + var options, name, src, copy, copyIsArray, clone, target = arguments[0] || {}, i = 1, length = arguments.length, deep = false; + if (typeof target === 'boolean') { + deep = target; + target = arguments[i] || {}; + i++; + } + if (typeof target !== 'object' && !isFunction(target)) { + target = {}; + } + if (i === length) { + target = this; + i--; + } + for (; i < length; i++) { + if ((options = arguments[i]) != null) { + for (name in options) { + src = target[name]; + copy = options[name]; + if (target === copy) { + continue; + } + if (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = Array.isArray(copy)))) { + if (copyIsArray) { + copyIsArray = false; + clone = src && Array.isArray(src) ? src : []; + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + target[name] = jQuery.extend(deep, clone, copy); + } else if (copy !== undefined) { + target[name] = copy; + } + } + } + } + return target; + }; + jQuery.extend({ + expando: 'jQuery' + (version + Math.random()).replace(/\D/g, ''), + isReady: true, + error: function (msg) { + throw new Error(msg); + }, + noop: function () { + }, + isPlainObject: function (obj) { + var proto, Ctor; + if (!obj || toString.call(obj) !== '[object Object]') { + return false; + } + proto = getProto(obj); + if (!proto) { + return true; + } + Ctor = hasOwn.call(proto, 'constructor') && proto.constructor; + return typeof Ctor === 'function' && fnToString.call(Ctor) === ObjectFunctionString; + }, + isEmptyObject: function (obj) { + var name; + for (name in obj) { + return false; + } + return true; + }, + globalEval: function (code) { + DOMEval(code); + }, + each: function (obj, callback) { + var length, i = 0; + if (isArrayLike(obj)) { + length = obj.length; + for (; i < length; i++) { + if (callback.call(obj[i], i, obj[i]) === false) { + break; + } + } + } else { + for (i in obj) { + if (callback.call(obj[i], i, obj[i]) === false) { + break; + } + } + } + return obj; + }, + trim: function (text) { + return text == null ? '' : (text + '').replace(rtrim, ''); + }, + makeArray: function (arr, results) { + var ret = results || []; + if (arr != null) { + if (isArrayLike(Object(arr))) { + jQuery.merge(ret, typeof arr === 'string' ? [arr] : arr); + } else { + push.call(ret, arr); + } + } + return ret; + }, + inArray: function (elem, arr, i) { + return arr == null ? -1 : indexOf.call(arr, elem, i); + }, + merge: function (first, second) { + var len = +second.length, j = 0, i = first.length; + for (; j < len; j++) { + first[i++] = second[j]; + } + first.length = i; + return first; + }, + grep: function (elems, callback, invert) { + var callbackInverse, matches = [], i = 0, length = elems.length, callbackExpect = !invert; + for (; i < length; i++) { + callbackInverse = !callback(elems[i], i); + if (callbackInverse !== callbackExpect) { + matches.push(elems[i]); + } + } + return matches; + }, + map: function (elems, callback, arg) { + var length, value, i = 0, ret = []; + if (isArrayLike(elems)) { + length = elems.length; + for (; i < length; i++) { + value = callback(elems[i], i, arg); + if (value != null) { + ret.push(value); + } + } + } else { + for (i in elems) { + value = callback(elems[i], i, arg); + if (value != null) { + ret.push(value); + } + } + } + return concat.apply([], ret); + }, + guid: 1, + support: support + }); + if (typeof Symbol === 'function') { + jQuery.fn[Symbol.iterator] = arr[Symbol.iterator]; + } + jQuery.each('Boolean Number String Function Array Date RegExp Object Error Symbol'.split(' '), function (i, name) { + class2type['[object ' + name + ']'] = name.toLowerCase(); + }); + function isArrayLike(obj) { + var length = !!obj && 'length' in obj && obj.length, type = toType(obj); + if (isFunction(obj) || isWindow(obj)) { + return false; + } + return type === 'array' || length === 0 || typeof length === 'number' && length > 0 && length - 1 in obj; + } + var Sizzle = function (window) { + var i, support, Expr, getText, isXML, tokenize, compile, select, outermostContext, sortInput, hasDuplicate, setDocument, document, docElem, documentIsHTML, rbuggyQSA, rbuggyMatches, matches, contains, expando = 'sizzle' + 1 * new Date(), preferredDoc = window.document, dirruns = 0, done = 0, classCache = createCache(), tokenCache = createCache(), compilerCache = createCache(), sortOrder = function (a, b) { + if (a === b) { + hasDuplicate = true; + } + return 0; + }, hasOwn = {}.hasOwnProperty, arr = [], pop = arr.pop, push_native = arr.push, push = arr.push, slice = arr.slice, indexOf = function (list, elem) { + var i = 0, len = list.length; + for (; i < len; i++) { + if (list[i] === elem) { + return i; + } + } + return -1; + }, booleans = 'checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped', whitespace = '[\\x20\\t\\r\\n\\f]', identifier = '(?:\\\\.|[\\w-]|[^\0-\\xa0])+', attributes = '\\[' + whitespace + '*(' + identifier + ')(?:' + whitespace + '*([*^$|!~]?=)' + whitespace + '*(?:\'((?:\\\\.|[^\\\\\'])*)\'|"((?:\\\\.|[^\\\\"])*)"|(' + identifier + '))|)' + whitespace + '*\\]', pseudos = ':(' + identifier + ')(?:\\((' + '(\'((?:\\\\.|[^\\\\\'])*)\'|"((?:\\\\.|[^\\\\"])*)")|' + '((?:\\\\.|[^\\\\()[\\]]|' + attributes + ')*)|' + '.*' + ')\\)|)', rwhitespace = new RegExp(whitespace + '+', 'g'), rtrim = new RegExp('^' + whitespace + '+|((?:^|[^\\\\])(?:\\\\.)*)' + whitespace + '+$', 'g'), rcomma = new RegExp('^' + whitespace + '*,' + whitespace + '*'), rcombinators = new RegExp('^' + whitespace + '*([>+~]|' + whitespace + ')' + whitespace + '*'), rattributeQuotes = new RegExp('=' + whitespace + '*([^\\]\'"]*?)' + whitespace + '*\\]', 'g'), rpseudo = new RegExp(pseudos), ridentifier = new RegExp('^' + identifier + '$'), matchExpr = { + 'ID': new RegExp('^#(' + identifier + ')'), + 'CLASS': new RegExp('^\\.(' + identifier + ')'), + 'TAG': new RegExp('^(' + identifier + '|[*])'), + 'ATTR': new RegExp('^' + attributes), + 'PSEUDO': new RegExp('^' + pseudos), + 'CHILD': new RegExp('^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(' + whitespace + '*(even|odd|(([+-]|)(\\d*)n|)' + whitespace + '*(?:([+-]|)' + whitespace + '*(\\d+)|))' + whitespace + '*\\)|)', 'i'), + 'bool': new RegExp('^(?:' + booleans + ')$', 'i'), + 'needsContext': new RegExp('^' + whitespace + '*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(' + whitespace + '*((?:-\\d)?\\d*)' + whitespace + '*\\)|)(?=[^-]|$)', 'i') + }, rinputs = /^(?:input|select|textarea|button)$/i, rheader = /^h\d$/i, rnative = /^[^{]+\{\s*\[native \w/, rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, rsibling = /[+~]/, runescape = new RegExp('\\\\([\\da-f]{1,6}' + whitespace + '?|(' + whitespace + ')|.)', 'ig'), funescape = function (_, escaped, escapedWhitespace) { + var high = '0x' + escaped - 65536; + return high !== high || escapedWhitespace ? escaped : high < 0 ? String.fromCharCode(high + 65536) : String.fromCharCode(high >> 10 | 55296, high & 1023 | 56320); + }, rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, fcssescape = function (ch, asCodePoint) { + if (asCodePoint) { + if (ch === '\0') { + return '\uFFFD'; + } + return ch.slice(0, -1) + '\\' + ch.charCodeAt(ch.length - 1).toString(16) + ' '; + } + return '\\' + ch; + }, unloadHandler = function () { + setDocument(); + }, disabledAncestor = addCombinator(function (elem) { + return elem.disabled === true && ('form' in elem || 'label' in elem); + }, { + dir: 'parentNode', + next: 'legend' + }); + try { + push.apply(arr = slice.call(preferredDoc.childNodes), preferredDoc.childNodes); + arr[preferredDoc.childNodes.length].nodeType; + } catch (e) { + push = { + apply: arr.length ? function (target, els) { + push_native.apply(target, slice.call(els)); + } : function (target, els) { + var j = target.length, i = 0; + while (target[j++] = els[i++]) { + } + target.length = j - 1; + } + }; + } + function Sizzle(selector, context, results, seed) { + var m, i, elem, nid, match, groups, newSelector, newContext = context && context.ownerDocument, nodeType = context ? context.nodeType : 9; + results = results || []; + if (typeof selector !== 'string' || !selector || nodeType !== 1 && nodeType !== 9 && nodeType !== 11) { + return results; + } + if (!seed) { + if ((context ? context.ownerDocument || context : preferredDoc) !== document) { + setDocument(context); + } + context = context || document; + if (documentIsHTML) { + if (nodeType !== 11 && (match = rquickExpr.exec(selector))) { + if (m = match[1]) { + if (nodeType === 9) { + if (elem = context.getElementById(m)) { + if (elem.id === m) { + results.push(elem); + return results; + } + } else { + return results; + } + } else { + if (newContext && (elem = newContext.getElementById(m)) && contains(context, elem) && elem.id === m) { + results.push(elem); + return results; + } + } + } else if (match[2]) { + push.apply(results, context.getElementsByTagName(selector)); + return results; + } else if ((m = match[3]) && support.getElementsByClassName && context.getElementsByClassName) { + push.apply(results, context.getElementsByClassName(m)); + return results; + } + } + if (support.qsa && !compilerCache[selector + ' '] && (!rbuggyQSA || !rbuggyQSA.test(selector))) { + if (nodeType !== 1) { + newContext = context; + newSelector = selector; + } else if (context.nodeName.toLowerCase() !== 'object') { + if (nid = context.getAttribute('id')) { + nid = nid.replace(rcssescape, fcssescape); + } else { + context.setAttribute('id', nid = expando); + } + groups = tokenize(selector); + i = groups.length; + while (i--) { + groups[i] = '#' + nid + ' ' + toSelector(groups[i]); + } + newSelector = groups.join(','); + newContext = rsibling.test(selector) && testContext(context.parentNode) || context; + } + if (newSelector) { + try { + push.apply(results, newContext.querySelectorAll(newSelector)); + return results; + } catch (qsaError) { + } finally { + if (nid === expando) { + context.removeAttribute('id'); + } + } + } + } + } + } + return select(selector.replace(rtrim, '$1'), context, results, seed); + } + function createCache() { + var keys = []; + function cache(key, value) { + if (keys.push(key + ' ') > Expr.cacheLength) { + delete cache[keys.shift()]; + } + return cache[key + ' '] = value; + } + return cache; + } + function markFunction(fn) { + fn[expando] = true; + return fn; + } + function assert(fn) { + var el = document.createElement('fieldset'); + try { + return !!fn(el); + } catch (e) { + return false; + } finally { + if (el.parentNode) { + el.parentNode.removeChild(el); + } + el = null; + } + } + function addHandle(attrs, handler) { + var arr = attrs.split('|'), i = arr.length; + while (i--) { + Expr.attrHandle[arr[i]] = handler; + } + } + function siblingCheck(a, b) { + var cur = b && a, diff = cur && a.nodeType === 1 && b.nodeType === 1 && a.sourceIndex - b.sourceIndex; + if (diff) { + return diff; + } + if (cur) { + while (cur = cur.nextSibling) { + if (cur === b) { + return -1; + } + } + } + return a ? 1 : -1; + } + function createInputPseudo(type) { + return function (elem) { + var name = elem.nodeName.toLowerCase(); + return name === 'input' && elem.type === type; + }; + } + function createButtonPseudo(type) { + return function (elem) { + var name = elem.nodeName.toLowerCase(); + return (name === 'input' || name === 'button') && elem.type === type; + }; + } + function createDisabledPseudo(disabled) { + return function (elem) { + if ('form' in elem) { + if (elem.parentNode && elem.disabled === false) { + if ('label' in elem) { + if ('label' in elem.parentNode) { + return elem.parentNode.disabled === disabled; + } else { + return elem.disabled === disabled; + } + } + return elem.isDisabled === disabled || elem.isDisabled !== !disabled && disabledAncestor(elem) === disabled; + } + return elem.disabled === disabled; + } else if ('label' in elem) { + return elem.disabled === disabled; + } + return false; + }; + } + function createPositionalPseudo(fn) { + return markFunction(function (argument) { + argument = +argument; + return markFunction(function (seed, matches) { + var j, matchIndexes = fn([], seed.length, argument), i = matchIndexes.length; + while (i--) { + if (seed[j = matchIndexes[i]]) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); + } + function testContext(context) { + return context && typeof context.getElementsByTagName !== 'undefined' && context; + } + support = Sizzle.support = {}; + isXML = Sizzle.isXML = function (elem) { + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== 'HTML' : false; + }; + setDocument = Sizzle.setDocument = function (node) { + var hasCompare, subWindow, doc = node ? node.ownerDocument || node : preferredDoc; + if (doc === document || doc.nodeType !== 9 || !doc.documentElement) { + return document; + } + document = doc; + docElem = document.documentElement; + documentIsHTML = !isXML(document); + if (preferredDoc !== document && (subWindow = document.defaultView) && subWindow.top !== subWindow) { + if (subWindow.addEventListener) { + subWindow.addEventListener('unload', unloadHandler, false); + } else if (subWindow.attachEvent) { + subWindow.attachEvent('onunload', unloadHandler); + } + } + support.attributes = assert(function (el) { + el.className = 'i'; + return !el.getAttribute('className'); + }); + support.getElementsByTagName = assert(function (el) { + el.appendChild(document.createComment('')); + return !el.getElementsByTagName('*').length; + }); + support.getElementsByClassName = rnative.test(document.getElementsByClassName); + support.getById = assert(function (el) { + docElem.appendChild(el).id = expando; + return !document.getElementsByName || !document.getElementsByName(expando).length; + }); + if (support.getById) { + Expr.filter['ID'] = function (id) { + var attrId = id.replace(runescape, funescape); + return function (elem) { + return elem.getAttribute('id') === attrId; + }; + }; + Expr.find['ID'] = function (id, context) { + if (typeof context.getElementById !== 'undefined' && documentIsHTML) { + var elem = context.getElementById(id); + return elem ? [elem] : []; + } + }; + } else { + Expr.filter['ID'] = function (id) { + var attrId = id.replace(runescape, funescape); + return function (elem) { + var node = typeof elem.getAttributeNode !== 'undefined' && elem.getAttributeNode('id'); + return node && node.value === attrId; + }; + }; + Expr.find['ID'] = function (id, context) { + if (typeof context.getElementById !== 'undefined' && documentIsHTML) { + var node, i, elems, elem = context.getElementById(id); + if (elem) { + node = elem.getAttributeNode('id'); + if (node && node.value === id) { + return [elem]; + } + elems = context.getElementsByName(id); + i = 0; + while (elem = elems[i++]) { + node = elem.getAttributeNode('id'); + if (node && node.value === id) { + return [elem]; + } + } + } + return []; + } + }; + } + Expr.find['TAG'] = support.getElementsByTagName ? function (tag, context) { + if (typeof context.getElementsByTagName !== 'undefined') { + return context.getElementsByTagName(tag); + } else if (support.qsa) { + return context.querySelectorAll(tag); + } + } : function (tag, context) { + var elem, tmp = [], i = 0, results = context.getElementsByTagName(tag); + if (tag === '*') { + while (elem = results[i++]) { + if (elem.nodeType === 1) { + tmp.push(elem); + } + } + return tmp; + } + return results; + }; + Expr.find['CLASS'] = support.getElementsByClassName && function (className, context) { + if (typeof context.getElementsByClassName !== 'undefined' && documentIsHTML) { + return context.getElementsByClassName(className); + } + }; + rbuggyMatches = []; + rbuggyQSA = []; + if (support.qsa = rnative.test(document.querySelectorAll)) { + assert(function (el) { + docElem.appendChild(el).innerHTML = '' + ''; + if (el.querySelectorAll('[msallowcapture^=\'\']').length) { + rbuggyQSA.push('[*^$]=' + whitespace + '*(?:\'\'|"")'); + } + if (!el.querySelectorAll('[selected]').length) { + rbuggyQSA.push('\\[' + whitespace + '*(?:value|' + booleans + ')'); + } + if (!el.querySelectorAll('[id~=' + expando + '-]').length) { + rbuggyQSA.push('~='); + } + if (!el.querySelectorAll(':checked').length) { + rbuggyQSA.push(':checked'); + } + if (!el.querySelectorAll('a#' + expando + '+*').length) { + rbuggyQSA.push('.#.+[+~]'); + } + }); + assert(function (el) { + el.innerHTML = '' + ''; + var input = document.createElement('input'); + input.setAttribute('type', 'hidden'); + el.appendChild(input).setAttribute('name', 'D'); + if (el.querySelectorAll('[name=d]').length) { + rbuggyQSA.push('name' + whitespace + '*[*^$|!~]?='); + } + if (el.querySelectorAll(':enabled').length !== 2) { + rbuggyQSA.push(':enabled', ':disabled'); + } + docElem.appendChild(el).disabled = true; + if (el.querySelectorAll(':disabled').length !== 2) { + rbuggyQSA.push(':enabled', ':disabled'); + } + el.querySelectorAll('*,:x'); + rbuggyQSA.push(',.*:'); + }); + } + if (support.matchesSelector = rnative.test(matches = docElem.matches || docElem.webkitMatchesSelector || docElem.mozMatchesSelector || docElem.oMatchesSelector || docElem.msMatchesSelector)) { + assert(function (el) { + support.disconnectedMatch = matches.call(el, '*'); + matches.call(el, '[s!=\'\']:x'); + rbuggyMatches.push('!=', pseudos); + }); + } + rbuggyQSA = rbuggyQSA.length && new RegExp(rbuggyQSA.join('|')); + rbuggyMatches = rbuggyMatches.length && new RegExp(rbuggyMatches.join('|')); + hasCompare = rnative.test(docElem.compareDocumentPosition); + contains = hasCompare || rnative.test(docElem.contains) ? function (a, b) { + var adown = a.nodeType === 9 ? a.documentElement : a, bup = b && b.parentNode; + return a === bup || !!(bup && bup.nodeType === 1 && (adown.contains ? adown.contains(bup) : a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16)); + } : function (a, b) { + if (b) { + while (b = b.parentNode) { + if (b === a) { + return true; + } + } + } + return false; + }; + sortOrder = hasCompare ? function (a, b) { + if (a === b) { + hasDuplicate = true; + return 0; + } + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if (compare) { + return compare; + } + compare = (a.ownerDocument || a) === (b.ownerDocument || b) ? a.compareDocumentPosition(b) : 1; + if (compare & 1 || !support.sortDetached && b.compareDocumentPosition(a) === compare) { + if (a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a)) { + return -1; + } + if (b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b)) { + return 1; + } + return sortInput ? indexOf(sortInput, a) - indexOf(sortInput, b) : 0; + } + return compare & 4 ? -1 : 1; + } : function (a, b) { + if (a === b) { + hasDuplicate = true; + return 0; + } + var cur, i = 0, aup = a.parentNode, bup = b.parentNode, ap = [a], bp = [b]; + if (!aup || !bup) { + return a === document ? -1 : b === document ? 1 : aup ? -1 : bup ? 1 : sortInput ? indexOf(sortInput, a) - indexOf(sortInput, b) : 0; + } else if (aup === bup) { + return siblingCheck(a, b); + } + cur = a; + while (cur = cur.parentNode) { + ap.unshift(cur); + } + cur = b; + while (cur = cur.parentNode) { + bp.unshift(cur); + } + while (ap[i] === bp[i]) { + i++; + } + return i ? siblingCheck(ap[i], bp[i]) : ap[i] === preferredDoc ? -1 : bp[i] === preferredDoc ? 1 : 0; + }; + return document; + }; + Sizzle.matches = function (expr, elements) { + return Sizzle(expr, null, null, elements); + }; + Sizzle.matchesSelector = function (elem, expr) { + if ((elem.ownerDocument || elem) !== document) { + setDocument(elem); + } + expr = expr.replace(rattributeQuotes, '=\'$1\']'); + if (support.matchesSelector && documentIsHTML && !compilerCache[expr + ' '] && (!rbuggyMatches || !rbuggyMatches.test(expr)) && (!rbuggyQSA || !rbuggyQSA.test(expr))) { + try { + var ret = matches.call(elem, expr); + if (ret || support.disconnectedMatch || elem.document && elem.document.nodeType !== 11) { + return ret; + } + } catch (e) { + } + } + return Sizzle(expr, document, null, [elem]).length > 0; + }; + Sizzle.contains = function (context, elem) { + if ((context.ownerDocument || context) !== document) { + setDocument(context); + } + return contains(context, elem); + }; + Sizzle.attr = function (elem, name) { + if ((elem.ownerDocument || elem) !== document) { + setDocument(elem); + } + var fn = Expr.attrHandle[name.toLowerCase()], val = fn && hasOwn.call(Expr.attrHandle, name.toLowerCase()) ? fn(elem, name, !documentIsHTML) : undefined; + return val !== undefined ? val : support.attributes || !documentIsHTML ? elem.getAttribute(name) : (val = elem.getAttributeNode(name)) && val.specified ? val.value : null; + }; + Sizzle.escape = function (sel) { + return (sel + '').replace(rcssescape, fcssescape); + }; + Sizzle.error = function (msg) { + throw new Error('Syntax error, unrecognized expression: ' + msg); + }; + Sizzle.uniqueSort = function (results) { + var elem, duplicates = [], j = 0, i = 0; + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice(0); + results.sort(sortOrder); + if (hasDuplicate) { + while (elem = results[i++]) { + if (elem === results[i]) { + j = duplicates.push(i); + } + } + while (j--) { + results.splice(duplicates[j], 1); + } + } + sortInput = null; + return results; + }; + getText = Sizzle.getText = function (elem) { + var node, ret = '', i = 0, nodeType = elem.nodeType; + if (!nodeType) { + while (node = elem[i++]) { + ret += getText(node); + } + } else if (nodeType === 1 || nodeType === 9 || nodeType === 11) { + if (typeof elem.textContent === 'string') { + return elem.textContent; + } else { + for (elem = elem.firstChild; elem; elem = elem.nextSibling) { + ret += getText(elem); + } + } + } else if (nodeType === 3 || nodeType === 4) { + return elem.nodeValue; + } + return ret; + }; + Expr = Sizzle.selectors = { + cacheLength: 50, + createPseudo: markFunction, + match: matchExpr, + attrHandle: {}, + find: {}, + relative: { + '>': { + dir: 'parentNode', + first: true + }, + ' ': { dir: 'parentNode' }, + '+': { + dir: 'previousSibling', + first: true + }, + '~': { dir: 'previousSibling' } + }, + preFilter: { + 'ATTR': function (match) { + match[1] = match[1].replace(runescape, funescape); + match[3] = (match[3] || match[4] || match[5] || '').replace(runescape, funescape); + if (match[2] === '~=') { + match[3] = ' ' + match[3] + ' '; + } + return match.slice(0, 4); + }, + 'CHILD': function (match) { + match[1] = match[1].toLowerCase(); + if (match[1].slice(0, 3) === 'nth') { + if (!match[3]) { + Sizzle.error(match[0]); + } + match[4] = +(match[4] ? match[5] + (match[6] || 1) : 2 * (match[3] === 'even' || match[3] === 'odd')); + match[5] = +(match[7] + match[8] || match[3] === 'odd'); + } else if (match[3]) { + Sizzle.error(match[0]); + } + return match; + }, + 'PSEUDO': function (match) { + var excess, unquoted = !match[6] && match[2]; + if (matchExpr['CHILD'].test(match[0])) { + return null; + } + if (match[3]) { + match[2] = match[4] || match[5] || ''; + } else if (unquoted && rpseudo.test(unquoted) && (excess = tokenize(unquoted, true)) && (excess = unquoted.indexOf(')', unquoted.length - excess) - unquoted.length)) { + match[0] = match[0].slice(0, excess); + match[2] = unquoted.slice(0, excess); + } + return match.slice(0, 3); + } + }, + filter: { + 'TAG': function (nodeNameSelector) { + var nodeName = nodeNameSelector.replace(runescape, funescape).toLowerCase(); + return nodeNameSelector === '*' ? function () { + return true; + } : function (elem) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + 'CLASS': function (className) { + var pattern = classCache[className + ' ']; + return pattern || (pattern = new RegExp('(^|' + whitespace + ')' + className + '(' + whitespace + '|$)')) && classCache(className, function (elem) { + return pattern.test(typeof elem.className === 'string' && elem.className || typeof elem.getAttribute !== 'undefined' && elem.getAttribute('class') || ''); + }); + }, + 'ATTR': function (name, operator, check) { + return function (elem) { + var result = Sizzle.attr(elem, name); + if (result == null) { + return operator === '!='; + } + if (!operator) { + return true; + } + result += ''; + return operator === '=' ? result === check : operator === '!=' ? result !== check : operator === '^=' ? check && result.indexOf(check) === 0 : operator === '*=' ? check && result.indexOf(check) > -1 : operator === '$=' ? check && result.slice(-check.length) === check : operator === '~=' ? (' ' + result.replace(rwhitespace, ' ') + ' ').indexOf(check) > -1 : operator === '|=' ? result === check || result.slice(0, check.length + 1) === check + '-' : false; + }; + }, + 'CHILD': function (type, what, argument, first, last) { + var simple = type.slice(0, 3) !== 'nth', forward = type.slice(-4) !== 'last', ofType = what === 'of-type'; + return first === 1 && last === 0 ? function (elem) { + return !!elem.parentNode; + } : function (elem, context, xml) { + var cache, uniqueCache, outerCache, node, nodeIndex, start, dir = simple !== forward ? 'nextSibling' : 'previousSibling', parent = elem.parentNode, name = ofType && elem.nodeName.toLowerCase(), useCache = !xml && !ofType, diff = false; + if (parent) { + if (simple) { + while (dir) { + node = elem; + while (node = node[dir]) { + if (ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) { + return false; + } + } + start = dir = type === 'only' && !start && 'nextSibling'; + } + return true; + } + start = [forward ? parent.firstChild : parent.lastChild]; + if (forward && useCache) { + node = parent; + outerCache = node[expando] || (node[expando] = {}); + uniqueCache = outerCache[node.uniqueID] || (outerCache[node.uniqueID] = {}); + cache = uniqueCache[type] || []; + nodeIndex = cache[0] === dirruns && cache[1]; + diff = nodeIndex && cache[2]; + node = nodeIndex && parent.childNodes[nodeIndex]; + while (node = ++nodeIndex && node && node[dir] || (diff = nodeIndex = 0) || start.pop()) { + if (node.nodeType === 1 && ++diff && node === elem) { + uniqueCache[type] = [ + dirruns, + nodeIndex, + diff + ]; + break; + } + } + } else { + if (useCache) { + node = elem; + outerCache = node[expando] || (node[expando] = {}); + uniqueCache = outerCache[node.uniqueID] || (outerCache[node.uniqueID] = {}); + cache = uniqueCache[type] || []; + nodeIndex = cache[0] === dirruns && cache[1]; + diff = nodeIndex; + } + if (diff === false) { + while (node = ++nodeIndex && node && node[dir] || (diff = nodeIndex = 0) || start.pop()) { + if ((ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) && ++diff) { + if (useCache) { + outerCache = node[expando] || (node[expando] = {}); + uniqueCache = outerCache[node.uniqueID] || (outerCache[node.uniqueID] = {}); + uniqueCache[type] = [ + dirruns, + diff + ]; + } + if (node === elem) { + break; + } + } + } + } + } + diff -= last; + return diff === first || diff % first === 0 && diff / first >= 0; + } + }; + }, + 'PSEUDO': function (pseudo, argument) { + var args, fn = Expr.pseudos[pseudo] || Expr.setFilters[pseudo.toLowerCase()] || Sizzle.error('unsupported pseudo: ' + pseudo); + if (fn[expando]) { + return fn(argument); + } + if (fn.length > 1) { + args = [ + pseudo, + pseudo, + '', + argument + ]; + return Expr.setFilters.hasOwnProperty(pseudo.toLowerCase()) ? markFunction(function (seed, matches) { + var idx, matched = fn(seed, argument), i = matched.length; + while (i--) { + idx = indexOf(seed, matched[i]); + seed[idx] = !(matches[idx] = matched[i]); + } + }) : function (elem) { + return fn(elem, 0, args); + }; + } + return fn; + } + }, + pseudos: { + 'not': markFunction(function (selector) { + var input = [], results = [], matcher = compile(selector.replace(rtrim, '$1')); + return matcher[expando] ? markFunction(function (seed, matches, context, xml) { + var elem, unmatched = matcher(seed, null, xml, []), i = seed.length; + while (i--) { + if (elem = unmatched[i]) { + seed[i] = !(matches[i] = elem); + } + } + }) : function (elem, context, xml) { + input[0] = elem; + matcher(input, null, xml, results); + input[0] = null; + return !results.pop(); + }; + }), + 'has': markFunction(function (selector) { + return function (elem) { + return Sizzle(selector, elem).length > 0; + }; + }), + 'contains': markFunction(function (text) { + text = text.replace(runescape, funescape); + return function (elem) { + return (elem.textContent || elem.innerText || getText(elem)).indexOf(text) > -1; + }; + }), + 'lang': markFunction(function (lang) { + if (!ridentifier.test(lang || '')) { + Sizzle.error('unsupported lang: ' + lang); + } + lang = lang.replace(runescape, funescape).toLowerCase(); + return function (elem) { + var elemLang; + do { + if (elemLang = documentIsHTML ? elem.lang : elem.getAttribute('xml:lang') || elem.getAttribute('lang')) { + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf(lang + '-') === 0; + } + } while ((elem = elem.parentNode) && elem.nodeType === 1); + return false; + }; + }), + 'target': function (elem) { + var hash = window.location && window.location.hash; + return hash && hash.slice(1) === elem.id; + }, + 'root': function (elem) { + return elem === docElem; + }, + 'focus': function (elem) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + 'enabled': createDisabledPseudo(false), + 'disabled': createDisabledPseudo(true), + 'checked': function (elem) { + var nodeName = elem.nodeName.toLowerCase(); + return nodeName === 'input' && !!elem.checked || nodeName === 'option' && !!elem.selected; + }, + 'selected': function (elem) { + if (elem.parentNode) { + elem.parentNode.selectedIndex; + } + return elem.selected === true; + }, + 'empty': function (elem) { + for (elem = elem.firstChild; elem; elem = elem.nextSibling) { + if (elem.nodeType < 6) { + return false; + } + } + return true; + }, + 'parent': function (elem) { + return !Expr.pseudos['empty'](elem); + }, + 'header': function (elem) { + return rheader.test(elem.nodeName); + }, + 'input': function (elem) { + return rinputs.test(elem.nodeName); + }, + 'button': function (elem) { + var name = elem.nodeName.toLowerCase(); + return name === 'input' && elem.type === 'button' || name === 'button'; + }, + 'text': function (elem) { + var attr; + return elem.nodeName.toLowerCase() === 'input' && elem.type === 'text' && ((attr = elem.getAttribute('type')) == null || attr.toLowerCase() === 'text'); + }, + 'first': createPositionalPseudo(function () { + return [0]; + }), + 'last': createPositionalPseudo(function (matchIndexes, length) { + return [length - 1]; + }), + 'eq': createPositionalPseudo(function (matchIndexes, length, argument) { + return [argument < 0 ? argument + length : argument]; + }), + 'even': createPositionalPseudo(function (matchIndexes, length) { + var i = 0; + for (; i < length; i += 2) { + matchIndexes.push(i); + } + return matchIndexes; + }), + 'odd': createPositionalPseudo(function (matchIndexes, length) { + var i = 1; + for (; i < length; i += 2) { + matchIndexes.push(i); + } + return matchIndexes; + }), + 'lt': createPositionalPseudo(function (matchIndexes, length, argument) { + var i = argument < 0 ? argument + length : argument; + for (; --i >= 0;) { + matchIndexes.push(i); + } + return matchIndexes; + }), + 'gt': createPositionalPseudo(function (matchIndexes, length, argument) { + var i = argument < 0 ? argument + length : argument; + for (; ++i < length;) { + matchIndexes.push(i); + } + return matchIndexes; + }) + } + }; + Expr.pseudos['nth'] = Expr.pseudos['eq']; + for (i in { + radio: true, + checkbox: true, + file: true, + password: true, + image: true + }) { + Expr.pseudos[i] = createInputPseudo(i); + } + for (i in { + submit: true, + reset: true + }) { + Expr.pseudos[i] = createButtonPseudo(i); + } + function setFilters() { + } + setFilters.prototype = Expr.filters = Expr.pseudos; + Expr.setFilters = new setFilters(); + tokenize = Sizzle.tokenize = function (selector, parseOnly) { + var matched, match, tokens, type, soFar, groups, preFilters, cached = tokenCache[selector + ' ']; + if (cached) { + return parseOnly ? 0 : cached.slice(0); + } + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + while (soFar) { + if (!matched || (match = rcomma.exec(soFar))) { + if (match) { + soFar = soFar.slice(match[0].length) || soFar; + } + groups.push(tokens = []); + } + matched = false; + if (match = rcombinators.exec(soFar)) { + matched = match.shift(); + tokens.push({ + value: matched, + type: match[0].replace(rtrim, ' ') + }); + soFar = soFar.slice(matched.length); + } + for (type in Expr.filter) { + if ((match = matchExpr[type].exec(soFar)) && (!preFilters[type] || (match = preFilters[type](match)))) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice(matched.length); + } + } + if (!matched) { + break; + } + } + return parseOnly ? soFar.length : soFar ? Sizzle.error(selector) : tokenCache(selector, groups).slice(0); + }; + function toSelector(tokens) { + var i = 0, len = tokens.length, selector = ''; + for (; i < len; i++) { + selector += tokens[i].value; + } + return selector; + } + function addCombinator(matcher, combinator, base) { + var dir = combinator.dir, skip = combinator.next, key = skip || dir, checkNonElements = base && key === 'parentNode', doneName = done++; + return combinator.first ? function (elem, context, xml) { + while (elem = elem[dir]) { + if (elem.nodeType === 1 || checkNonElements) { + return matcher(elem, context, xml); + } + } + return false; + } : function (elem, context, xml) { + var oldCache, uniqueCache, outerCache, newCache = [ + dirruns, + doneName + ]; + if (xml) { + while (elem = elem[dir]) { + if (elem.nodeType === 1 || checkNonElements) { + if (matcher(elem, context, xml)) { + return true; + } + } + } + } else { + while (elem = elem[dir]) { + if (elem.nodeType === 1 || checkNonElements) { + outerCache = elem[expando] || (elem[expando] = {}); + uniqueCache = outerCache[elem.uniqueID] || (outerCache[elem.uniqueID] = {}); + if (skip && skip === elem.nodeName.toLowerCase()) { + elem = elem[dir] || elem; + } else if ((oldCache = uniqueCache[key]) && oldCache[0] === dirruns && oldCache[1] === doneName) { + return newCache[2] = oldCache[2]; + } else { + uniqueCache[key] = newCache; + if (newCache[2] = matcher(elem, context, xml)) { + return true; + } + } + } + } + } + return false; + }; + } + function elementMatcher(matchers) { + return matchers.length > 1 ? function (elem, context, xml) { + var i = matchers.length; + while (i--) { + if (!matchers[i](elem, context, xml)) { + return false; + } + } + return true; + } : matchers[0]; + } + function multipleContexts(selector, contexts, results) { + var i = 0, len = contexts.length; + for (; i < len; i++) { + Sizzle(selector, contexts[i], results); + } + return results; + } + function condense(unmatched, map, filter, context, xml) { + var elem, newUnmatched = [], i = 0, len = unmatched.length, mapped = map != null; + for (; i < len; i++) { + if (elem = unmatched[i]) { + if (!filter || filter(elem, context, xml)) { + newUnmatched.push(elem); + if (mapped) { + map.push(i); + } + } + } + } + return newUnmatched; + } + function setMatcher(preFilter, selector, matcher, postFilter, postFinder, postSelector) { + if (postFilter && !postFilter[expando]) { + postFilter = setMatcher(postFilter); + } + if (postFinder && !postFinder[expando]) { + postFinder = setMatcher(postFinder, postSelector); + } + return markFunction(function (seed, results, context, xml) { + var temp, i, elem, preMap = [], postMap = [], preexisting = results.length, elems = seed || multipleContexts(selector || '*', context.nodeType ? [context] : context, []), matcherIn = preFilter && (seed || !selector) ? condense(elems, preMap, preFilter, context, xml) : elems, matcherOut = matcher ? postFinder || (seed ? preFilter : preexisting || postFilter) ? [] : results : matcherIn; + if (matcher) { + matcher(matcherIn, matcherOut, context, xml); + } + if (postFilter) { + temp = condense(matcherOut, postMap); + postFilter(temp, [], context, xml); + i = temp.length; + while (i--) { + if (elem = temp[i]) { + matcherOut[postMap[i]] = !(matcherIn[postMap[i]] = elem); + } + } + } + if (seed) { + if (postFinder || preFilter) { + if (postFinder) { + temp = []; + i = matcherOut.length; + while (i--) { + if (elem = matcherOut[i]) { + temp.push(matcherIn[i] = elem); + } + } + postFinder(null, matcherOut = [], temp, xml); + } + i = matcherOut.length; + while (i--) { + if ((elem = matcherOut[i]) && (temp = postFinder ? indexOf(seed, elem) : preMap[i]) > -1) { + seed[temp] = !(results[temp] = elem); + } + } + } + } else { + matcherOut = condense(matcherOut === results ? matcherOut.splice(preexisting, matcherOut.length) : matcherOut); + if (postFinder) { + postFinder(null, results, matcherOut, xml); + } else { + push.apply(results, matcherOut); + } + } + }); + } + function matcherFromTokens(tokens) { + var checkContext, matcher, j, len = tokens.length, leadingRelative = Expr.relative[tokens[0].type], implicitRelative = leadingRelative || Expr.relative[' '], i = leadingRelative ? 1 : 0, matchContext = addCombinator(function (elem) { + return elem === checkContext; + }, implicitRelative, true), matchAnyContext = addCombinator(function (elem) { + return indexOf(checkContext, elem) > -1; + }, implicitRelative, true), matchers = [function (elem, context, xml) { + var ret = !leadingRelative && (xml || context !== outermostContext) || ((checkContext = context).nodeType ? matchContext(elem, context, xml) : matchAnyContext(elem, context, xml)); + checkContext = null; + return ret; + }]; + for (; i < len; i++) { + if (matcher = Expr.relative[tokens[i].type]) { + matchers = [addCombinator(elementMatcher(matchers), matcher)]; + } else { + matcher = Expr.filter[tokens[i].type].apply(null, tokens[i].matches); + if (matcher[expando]) { + j = ++i; + for (; j < len; j++) { + if (Expr.relative[tokens[j].type]) { + break; + } + } + return setMatcher(i > 1 && elementMatcher(matchers), i > 1 && toSelector(tokens.slice(0, i - 1).concat({ value: tokens[i - 2].type === ' ' ? '*' : '' })).replace(rtrim, '$1'), matcher, i < j && matcherFromTokens(tokens.slice(i, j)), j < len && matcherFromTokens(tokens = tokens.slice(j)), j < len && toSelector(tokens)); + } + matchers.push(matcher); + } + } + return elementMatcher(matchers); + } + function matcherFromGroupMatchers(elementMatchers, setMatchers) { + var bySet = setMatchers.length > 0, byElement = elementMatchers.length > 0, superMatcher = function (seed, context, xml, results, outermost) { + var elem, j, matcher, matchedCount = 0, i = '0', unmatched = seed && [], setMatched = [], contextBackup = outermostContext, elems = seed || byElement && Expr.find['TAG']('*', outermost), dirrunsUnique = dirruns += contextBackup == null ? 1 : Math.random() || 0.1, len = elems.length; + if (outermost) { + outermostContext = context === document || context || outermost; + } + for (; i !== len && (elem = elems[i]) != null; i++) { + if (byElement && elem) { + j = 0; + if (!context && elem.ownerDocument !== document) { + setDocument(elem); + xml = !documentIsHTML; + } + while (matcher = elementMatchers[j++]) { + if (matcher(elem, context || document, xml)) { + results.push(elem); + break; + } + } + if (outermost) { + dirruns = dirrunsUnique; + } + } + if (bySet) { + if (elem = !matcher && elem) { + matchedCount--; + } + if (seed) { + unmatched.push(elem); + } + } + } + matchedCount += i; + if (bySet && i !== matchedCount) { + j = 0; + while (matcher = setMatchers[j++]) { + matcher(unmatched, setMatched, context, xml); + } + if (seed) { + if (matchedCount > 0) { + while (i--) { + if (!(unmatched[i] || setMatched[i])) { + setMatched[i] = pop.call(results); + } + } + } + setMatched = condense(setMatched); + } + push.apply(results, setMatched); + if (outermost && !seed && setMatched.length > 0 && matchedCount + setMatchers.length > 1) { + Sizzle.uniqueSort(results); + } + } + if (outermost) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + return unmatched; + }; + return bySet ? markFunction(superMatcher) : superMatcher; + } + compile = Sizzle.compile = function (selector, match) { + var i, setMatchers = [], elementMatchers = [], cached = compilerCache[selector + ' ']; + if (!cached) { + if (!match) { + match = tokenize(selector); + } + i = match.length; + while (i--) { + cached = matcherFromTokens(match[i]); + if (cached[expando]) { + setMatchers.push(cached); + } else { + elementMatchers.push(cached); + } + } + cached = compilerCache(selector, matcherFromGroupMatchers(elementMatchers, setMatchers)); + cached.selector = selector; + } + return cached; + }; + select = Sizzle.select = function (selector, context, results, seed) { + var i, tokens, token, type, find, compiled = typeof selector === 'function' && selector, match = !seed && tokenize(selector = compiled.selector || selector); + results = results || []; + if (match.length === 1) { + tokens = match[0] = match[0].slice(0); + if (tokens.length > 2 && (token = tokens[0]).type === 'ID' && context.nodeType === 9 && documentIsHTML && Expr.relative[tokens[1].type]) { + context = (Expr.find['ID'](token.matches[0].replace(runescape, funescape), context) || [])[0]; + if (!context) { + return results; + } else if (compiled) { + context = context.parentNode; + } + selector = selector.slice(tokens.shift().value.length); + } + i = matchExpr['needsContext'].test(selector) ? 0 : tokens.length; + while (i--) { + token = tokens[i]; + if (Expr.relative[type = token.type]) { + break; + } + if (find = Expr.find[type]) { + if (seed = find(token.matches[0].replace(runescape, funescape), rsibling.test(tokens[0].type) && testContext(context.parentNode) || context)) { + tokens.splice(i, 1); + selector = seed.length && toSelector(tokens); + if (!selector) { + push.apply(results, seed); + return results; + } + break; + } + } + } + } + (compiled || compile(selector, match))(seed, context, !documentIsHTML, results, !context || rsibling.test(selector) && testContext(context.parentNode) || context); + return results; + }; + support.sortStable = expando.split('').sort(sortOrder).join('') === expando; + support.detectDuplicates = !!hasDuplicate; + setDocument(); + support.sortDetached = assert(function (el) { + return el.compareDocumentPosition(document.createElement('fieldset')) & 1; + }); + if (!assert(function (el) { + el.innerHTML = ''; + return el.firstChild.getAttribute('href') === '#'; + })) { + addHandle('type|href|height|width', function (elem, name, isXML) { + if (!isXML) { + return elem.getAttribute(name, name.toLowerCase() === 'type' ? 1 : 2); + } + }); + } + if (!support.attributes || !assert(function (el) { + el.innerHTML = ''; + el.firstChild.setAttribute('value', ''); + return el.firstChild.getAttribute('value') === ''; + })) { + addHandle('value', function (elem, name, isXML) { + if (!isXML && elem.nodeName.toLowerCase() === 'input') { + return elem.defaultValue; + } + }); + } + if (!assert(function (el) { + return el.getAttribute('disabled') == null; + })) { + addHandle(booleans, function (elem, name, isXML) { + var val; + if (!isXML) { + return elem[name] === true ? name.toLowerCase() : (val = elem.getAttributeNode(name)) && val.specified ? val.value : null; + } + }); + } + return Sizzle; + }(window); + jQuery.find = Sizzle; + jQuery.expr = Sizzle.selectors; + jQuery.expr[':'] = jQuery.expr.pseudos; + jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; + jQuery.text = Sizzle.getText; + jQuery.isXMLDoc = Sizzle.isXML; + jQuery.contains = Sizzle.contains; + jQuery.escapeSelector = Sizzle.escape; + var dir = function (elem, dir, until) { + var matched = [], truncate = until !== undefined; + while ((elem = elem[dir]) && elem.nodeType !== 9) { + if (elem.nodeType === 1) { + if (truncate && jQuery(elem).is(until)) { + break; + } + matched.push(elem); + } + } + return matched; + }; + var siblings = function (n, elem) { + var matched = []; + for (; n; n = n.nextSibling) { + if (n.nodeType === 1 && n !== elem) { + matched.push(n); + } + } + return matched; + }; + var rneedsContext = jQuery.expr.match.needsContext; + function nodeName(elem, name) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + } + ; + var rsingleTag = /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i; + function winnow(elements, qualifier, not) { + if (isFunction(qualifier)) { + return jQuery.grep(elements, function (elem, i) { + return !!qualifier.call(elem, i, elem) !== not; + }); + } + if (qualifier.nodeType) { + return jQuery.grep(elements, function (elem) { + return elem === qualifier !== not; + }); + } + if (typeof qualifier !== 'string') { + return jQuery.grep(elements, function (elem) { + return indexOf.call(qualifier, elem) > -1 !== not; + }); + } + return jQuery.filter(qualifier, elements, not); + } + jQuery.filter = function (expr, elems, not) { + var elem = elems[0]; + if (not) { + expr = ':not(' + expr + ')'; + } + if (elems.length === 1 && elem.nodeType === 1) { + return jQuery.find.matchesSelector(elem, expr) ? [elem] : []; + } + return jQuery.find.matches(expr, jQuery.grep(elems, function (elem) { + return elem.nodeType === 1; + })); + }; + jQuery.fn.extend({ + find: function (selector) { + var i, ret, len = this.length, self = this; + if (typeof selector !== 'string') { + return this.pushStack(jQuery(selector).filter(function () { + for (i = 0; i < len; i++) { + if (jQuery.contains(self[i], this)) { + return true; + } + } + })); + } + ret = this.pushStack([]); + for (i = 0; i < len; i++) { + jQuery.find(selector, self[i], ret); + } + return len > 1 ? jQuery.uniqueSort(ret) : ret; + }, + filter: function (selector) { + return this.pushStack(winnow(this, selector || [], false)); + }, + not: function (selector) { + return this.pushStack(winnow(this, selector || [], true)); + }, + is: function (selector) { + return !!winnow(this, typeof selector === 'string' && rneedsContext.test(selector) ? jQuery(selector) : selector || [], false).length; + } + }); + var rootjQuery, rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, init = jQuery.fn.init = function (selector, context, root) { + var match, elem; + if (!selector) { + return this; + } + root = root || rootjQuery; + if (typeof selector === 'string') { + if (selector[0] === '<' && selector[selector.length - 1] === '>' && selector.length >= 3) { + match = [ + null, + selector, + null + ]; + } else { + match = rquickExpr.exec(selector); + } + if (match && (match[1] || !context)) { + if (match[1]) { + context = context instanceof jQuery ? context[0] : context; + jQuery.merge(this, jQuery.parseHTML(match[1], context && context.nodeType ? context.ownerDocument || context : document, true)); + if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) { + for (match in context) { + if (isFunction(this[match])) { + this[match](context[match]); + } else { + this.attr(match, context[match]); + } + } + } + return this; + } else { + elem = document.getElementById(match[2]); + if (elem) { + this[0] = elem; + this.length = 1; + } + return this; + } + } else if (!context || context.jquery) { + return (context || root).find(selector); + } else { + return this.constructor(context).find(selector); + } + } else if (selector.nodeType) { + this[0] = selector; + this.length = 1; + return this; + } else if (isFunction(selector)) { + return root.ready !== undefined ? root.ready(selector) : selector(jQuery); + } + return jQuery.makeArray(selector, this); + }; + init.prototype = jQuery.fn; + rootjQuery = jQuery(document); + var rparentsprev = /^(?:parents|prev(?:Until|All))/, guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + jQuery.fn.extend({ + has: function (target) { + var targets = jQuery(target, this), l = targets.length; + return this.filter(function () { + var i = 0; + for (; i < l; i++) { + if (jQuery.contains(this, targets[i])) { + return true; + } + } + }); + }, + closest: function (selectors, context) { + var cur, i = 0, l = this.length, matched = [], targets = typeof selectors !== 'string' && jQuery(selectors); + if (!rneedsContext.test(selectors)) { + for (; i < l; i++) { + for (cur = this[i]; cur && cur !== context; cur = cur.parentNode) { + if (cur.nodeType < 11 && (targets ? targets.index(cur) > -1 : cur.nodeType === 1 && jQuery.find.matchesSelector(cur, selectors))) { + matched.push(cur); + break; + } + } + } + } + return this.pushStack(matched.length > 1 ? jQuery.uniqueSort(matched) : matched); + }, + index: function (elem) { + if (!elem) { + return this[0] && this[0].parentNode ? this.first().prevAll().length : -1; + } + if (typeof elem === 'string') { + return indexOf.call(jQuery(elem), this[0]); + } + return indexOf.call(this, elem.jquery ? elem[0] : elem); + }, + add: function (selector, context) { + return this.pushStack(jQuery.uniqueSort(jQuery.merge(this.get(), jQuery(selector, context)))); + }, + addBack: function (selector) { + return this.add(selector == null ? this.prevObject : this.prevObject.filter(selector)); + } + }); + function sibling(cur, dir) { + while ((cur = cur[dir]) && cur.nodeType !== 1) { + } + return cur; + } + jQuery.each({ + parent: function (elem) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function (elem) { + return dir(elem, 'parentNode'); + }, + parentsUntil: function (elem, i, until) { + return dir(elem, 'parentNode', until); + }, + next: function (elem) { + return sibling(elem, 'nextSibling'); + }, + prev: function (elem) { + return sibling(elem, 'previousSibling'); + }, + nextAll: function (elem) { + return dir(elem, 'nextSibling'); + }, + prevAll: function (elem) { + return dir(elem, 'previousSibling'); + }, + nextUntil: function (elem, i, until) { + return dir(elem, 'nextSibling', until); + }, + prevUntil: function (elem, i, until) { + return dir(elem, 'previousSibling', until); + }, + siblings: function (elem) { + return siblings((elem.parentNode || {}).firstChild, elem); + }, + children: function (elem) { + return siblings(elem.firstChild); + }, + contents: function (elem) { + if (nodeName(elem, 'iframe')) { + return elem.contentDocument; + } + if (nodeName(elem, 'template')) { + elem = elem.content || elem; + } + return jQuery.merge([], elem.childNodes); + } + }, function (name, fn) { + jQuery.fn[name] = function (until, selector) { + var matched = jQuery.map(this, fn, until); + if (name.slice(-5) !== 'Until') { + selector = until; + } + if (selector && typeof selector === 'string') { + matched = jQuery.filter(selector, matched); + } + if (this.length > 1) { + if (!guaranteedUnique[name]) { + jQuery.uniqueSort(matched); + } + if (rparentsprev.test(name)) { + matched.reverse(); + } + } + return this.pushStack(matched); + }; + }); + var rnothtmlwhite = /[^\x20\t\r\n\f]+/g; + function createOptions(options) { + var object = {}; + jQuery.each(options.match(rnothtmlwhite) || [], function (_, flag) { + object[flag] = true; + }); + return object; + } + jQuery.Callbacks = function (options) { + options = typeof options === 'string' ? createOptions(options) : jQuery.extend({}, options); + var firing, memory, fired, locked, list = [], queue = [], firingIndex = -1, fire = function () { + locked = locked || options.once; + fired = firing = true; + for (; queue.length; firingIndex = -1) { + memory = queue.shift(); + while (++firingIndex < list.length) { + if (list[firingIndex].apply(memory[0], memory[1]) === false && options.stopOnFalse) { + firingIndex = list.length; + memory = false; + } + } + } + if (!options.memory) { + memory = false; + } + firing = false; + if (locked) { + if (memory) { + list = []; + } else { + list = ''; + } + } + }, self = { + add: function () { + if (list) { + if (memory && !firing) { + firingIndex = list.length - 1; + queue.push(memory); + } + (function add(args) { + jQuery.each(args, function (_, arg) { + if (isFunction(arg)) { + if (!options.unique || !self.has(arg)) { + list.push(arg); + } + } else if (arg && arg.length && toType(arg) !== 'string') { + add(arg); + } + }); + }(arguments)); + if (memory && !firing) { + fire(); + } + } + return this; + }, + remove: function () { + jQuery.each(arguments, function (_, arg) { + var index; + while ((index = jQuery.inArray(arg, list, index)) > -1) { + list.splice(index, 1); + if (index <= firingIndex) { + firingIndex--; + } + } + }); + return this; + }, + has: function (fn) { + return fn ? jQuery.inArray(fn, list) > -1 : list.length > 0; + }, + empty: function () { + if (list) { + list = []; + } + return this; + }, + disable: function () { + locked = queue = []; + list = memory = ''; + return this; + }, + disabled: function () { + return !list; + }, + lock: function () { + locked = queue = []; + if (!memory && !firing) { + list = memory = ''; + } + return this; + }, + locked: function () { + return !!locked; + }, + fireWith: function (context, args) { + if (!locked) { + args = args || []; + args = [ + context, + args.slice ? args.slice() : args + ]; + queue.push(args); + if (!firing) { + fire(); + } + } + return this; + }, + fire: function () { + self.fireWith(this, arguments); + return this; + }, + fired: function () { + return !!fired; + } + }; + return self; + }; + function Identity(v) { + return v; + } + function Thrower(ex) { + throw ex; + } + function adoptValue(value, resolve, reject, noValue) { + var method; + try { + if (value && isFunction(method = value.promise)) { + method.call(value).done(resolve).fail(reject); + } else if (value && isFunction(method = value.then)) { + method.call(value, resolve, reject); + } else { + resolve.apply(undefined, [value].slice(noValue)); + } + } catch (value) { + reject.apply(undefined, [value]); + } + } + jQuery.extend({ + Deferred: function (func) { + var tuples = [ + [ + 'notify', + 'progress', + jQuery.Callbacks('memory'), + jQuery.Callbacks('memory'), + 2 + ], + [ + 'resolve', + 'done', + jQuery.Callbacks('once memory'), + jQuery.Callbacks('once memory'), + 0, + 'resolved' + ], + [ + 'reject', + 'fail', + jQuery.Callbacks('once memory'), + jQuery.Callbacks('once memory'), + 1, + 'rejected' + ] + ], state = 'pending', promise = { + state: function () { + return state; + }, + always: function () { + deferred.done(arguments).fail(arguments); + return this; + }, + 'catch': function (fn) { + return promise.then(null, fn); + }, + pipe: function () { + var fns = arguments; + return jQuery.Deferred(function (newDefer) { + jQuery.each(tuples, function (i, tuple) { + var fn = isFunction(fns[tuple[4]]) && fns[tuple[4]]; + deferred[tuple[1]](function () { + var returned = fn && fn.apply(this, arguments); + if (returned && isFunction(returned.promise)) { + returned.promise().progress(newDefer.notify).done(newDefer.resolve).fail(newDefer.reject); + } else { + newDefer[tuple[0] + 'With'](this, fn ? [returned] : arguments); + } + }); + }); + fns = null; + }).promise(); + }, + then: function (onFulfilled, onRejected, onProgress) { + var maxDepth = 0; + function resolve(depth, deferred, handler, special) { + return function () { + var that = this, args = arguments, mightThrow = function () { + var returned, then; + if (depth < maxDepth) { + return; + } + returned = handler.apply(that, args); + if (returned === deferred.promise()) { + throw new TypeError('Thenable self-resolution'); + } + then = returned && (typeof returned === 'object' || typeof returned === 'function') && returned.then; + if (isFunction(then)) { + if (special) { + then.call(returned, resolve(maxDepth, deferred, Identity, special), resolve(maxDepth, deferred, Thrower, special)); + } else { + maxDepth++; + then.call(returned, resolve(maxDepth, deferred, Identity, special), resolve(maxDepth, deferred, Thrower, special), resolve(maxDepth, deferred, Identity, deferred.notifyWith)); + } + } else { + if (handler !== Identity) { + that = undefined; + args = [returned]; + } + (special || deferred.resolveWith)(that, args); + } + }, process = special ? mightThrow : function () { + try { + mightThrow(); + } catch (e) { + if (jQuery.Deferred.exceptionHook) { + jQuery.Deferred.exceptionHook(e, process.stackTrace); + } + if (depth + 1 >= maxDepth) { + if (handler !== Thrower) { + that = undefined; + args = [e]; + } + deferred.rejectWith(that, args); + } + } + }; + if (depth) { + process(); + } else { + if (jQuery.Deferred.getStackHook) { + process.stackTrace = jQuery.Deferred.getStackHook(); + } + window.setTimeout(process); + } + }; + } + return jQuery.Deferred(function (newDefer) { + tuples[0][3].add(resolve(0, newDefer, isFunction(onProgress) ? onProgress : Identity, newDefer.notifyWith)); + tuples[1][3].add(resolve(0, newDefer, isFunction(onFulfilled) ? onFulfilled : Identity)); + tuples[2][3].add(resolve(0, newDefer, isFunction(onRejected) ? onRejected : Thrower)); + }).promise(); + }, + promise: function (obj) { + return obj != null ? jQuery.extend(obj, promise) : promise; + } + }, deferred = {}; + jQuery.each(tuples, function (i, tuple) { + var list = tuple[2], stateString = tuple[5]; + promise[tuple[1]] = list.add; + if (stateString) { + list.add(function () { + state = stateString; + }, tuples[3 - i][2].disable, tuples[3 - i][3].disable, tuples[0][2].lock, tuples[0][3].lock); + } + list.add(tuple[3].fire); + deferred[tuple[0]] = function () { + deferred[tuple[0] + 'With'](this === deferred ? undefined : this, arguments); + return this; + }; + deferred[tuple[0] + 'With'] = list.fireWith; + }); + promise.promise(deferred); + if (func) { + func.call(deferred, deferred); + } + return deferred; + }, + when: function (singleValue) { + var remaining = arguments.length, i = remaining, resolveContexts = Array(i), resolveValues = slice.call(arguments), master = jQuery.Deferred(), updateFunc = function (i) { + return function (value) { + resolveContexts[i] = this; + resolveValues[i] = arguments.length > 1 ? slice.call(arguments) : value; + if (!--remaining) { + master.resolveWith(resolveContexts, resolveValues); + } + }; + }; + if (remaining <= 1) { + adoptValue(singleValue, master.done(updateFunc(i)).resolve, master.reject, !remaining); + if (master.state() === 'pending' || isFunction(resolveValues[i] && resolveValues[i].then)) { + return master.then(); + } + } + while (i--) { + adoptValue(resolveValues[i], updateFunc(i), master.reject); + } + return master.promise(); + } + }); + var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; + jQuery.Deferred.exceptionHook = function (error, stack) { + if (window.console && window.console.warn && error && rerrorNames.test(error.name)) { + window.console.warn('jQuery.Deferred exception: ' + error.message, error.stack, stack); + } + }; + jQuery.readyException = function (error) { + window.setTimeout(function () { + throw error; + }); + }; + var readyList = jQuery.Deferred(); + jQuery.fn.ready = function (fn) { + readyList.then(fn).catch(function (error) { + jQuery.readyException(error); + }); + return this; + }; + jQuery.extend({ + isReady: false, + readyWait: 1, + ready: function (wait) { + if (wait === true ? --jQuery.readyWait : jQuery.isReady) { + return; + } + jQuery.isReady = true; + if (wait !== true && --jQuery.readyWait > 0) { + return; + } + readyList.resolveWith(document, [jQuery]); + } + }); + jQuery.ready.then = readyList.then; + function completed() { + document.removeEventListener('DOMContentLoaded', completed); + window.removeEventListener('load', completed); + jQuery.ready(); + } + if (document.readyState === 'complete' || document.readyState !== 'loading' && !document.documentElement.doScroll) { + window.setTimeout(jQuery.ready); + } else { + document.addEventListener('DOMContentLoaded', completed); + window.addEventListener('load', completed); + } + var access = function (elems, fn, key, value, chainable, emptyGet, raw) { + var i = 0, len = elems.length, bulk = key == null; + if (toType(key) === 'object') { + chainable = true; + for (i in key) { + access(elems, fn, i, key[i], true, emptyGet, raw); + } + } else if (value !== undefined) { + chainable = true; + if (!isFunction(value)) { + raw = true; + } + if (bulk) { + if (raw) { + fn.call(elems, value); + fn = null; + } else { + bulk = fn; + fn = function (elem, key, value) { + return bulk.call(jQuery(elem), value); + }; + } + } + if (fn) { + for (; i < len; i++) { + fn(elems[i], key, raw ? value : value.call(elems[i], i, fn(elems[i], key))); + } + } + } + if (chainable) { + return elems; + } + if (bulk) { + return fn.call(elems); + } + return len ? fn(elems[0], key) : emptyGet; + }; + var rmsPrefix = /^-ms-/, rdashAlpha = /-([a-z])/g; + function fcamelCase(all, letter) { + return letter.toUpperCase(); + } + function camelCase(string) { + return string.replace(rmsPrefix, 'ms-').replace(rdashAlpha, fcamelCase); + } + var acceptData = function (owner) { + return owner.nodeType === 1 || owner.nodeType === 9 || !+owner.nodeType; + }; + function Data() { + this.expando = jQuery.expando + Data.uid++; + } + Data.uid = 1; + Data.prototype = { + cache: function (owner) { + var value = owner[this.expando]; + if (!value) { + value = {}; + if (acceptData(owner)) { + if (owner.nodeType) { + owner[this.expando] = value; + } else { + Object.defineProperty(owner, this.expando, { + value: value, + configurable: true + }); + } + } + } + return value; + }, + set: function (owner, data, value) { + var prop, cache = this.cache(owner); + if (typeof data === 'string') { + cache[camelCase(data)] = value; + } else { + for (prop in data) { + cache[camelCase(prop)] = data[prop]; + } + } + return cache; + }, + get: function (owner, key) { + return key === undefined ? this.cache(owner) : owner[this.expando] && owner[this.expando][camelCase(key)]; + }, + access: function (owner, key, value) { + if (key === undefined || key && typeof key === 'string' && value === undefined) { + return this.get(owner, key); + } + this.set(owner, key, value); + return value !== undefined ? value : key; + }, + remove: function (owner, key) { + var i, cache = owner[this.expando]; + if (cache === undefined) { + return; + } + if (key !== undefined) { + if (Array.isArray(key)) { + key = key.map(camelCase); + } else { + key = camelCase(key); + key = key in cache ? [key] : key.match(rnothtmlwhite) || []; + } + i = key.length; + while (i--) { + delete cache[key[i]]; + } + } + if (key === undefined || jQuery.isEmptyObject(cache)) { + if (owner.nodeType) { + owner[this.expando] = undefined; + } else { + delete owner[this.expando]; + } + } + }, + hasData: function (owner) { + var cache = owner[this.expando]; + return cache !== undefined && !jQuery.isEmptyObject(cache); + } + }; + var dataPriv = new Data(); + var dataUser = new Data(); + var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, rmultiDash = /[A-Z]/g; + function getData(data) { + if (data === 'true') { + return true; + } + if (data === 'false') { + return false; + } + if (data === 'null') { + return null; + } + if (data === +data + '') { + return +data; + } + if (rbrace.test(data)) { + return JSON.parse(data); + } + return data; + } + function dataAttr(elem, key, data) { + var name; + if (data === undefined && elem.nodeType === 1) { + name = 'data-' + key.replace(rmultiDash, '-$&').toLowerCase(); + data = elem.getAttribute(name); + if (typeof data === 'string') { + try { + data = getData(data); + } catch (e) { + } + dataUser.set(elem, key, data); + } else { + data = undefined; + } + } + return data; + } + jQuery.extend({ + hasData: function (elem) { + return dataUser.hasData(elem) || dataPriv.hasData(elem); + }, + data: function (elem, name, data) { + return dataUser.access(elem, name, data); + }, + removeData: function (elem, name) { + dataUser.remove(elem, name); + }, + _data: function (elem, name, data) { + return dataPriv.access(elem, name, data); + }, + _removeData: function (elem, name) { + dataPriv.remove(elem, name); + } + }); + jQuery.fn.extend({ + data: function (key, value) { + var i, name, data, elem = this[0], attrs = elem && elem.attributes; + if (key === undefined) { + if (this.length) { + data = dataUser.get(elem); + if (elem.nodeType === 1 && !dataPriv.get(elem, 'hasDataAttrs')) { + i = attrs.length; + while (i--) { + if (attrs[i]) { + name = attrs[i].name; + if (name.indexOf('data-') === 0) { + name = camelCase(name.slice(5)); + dataAttr(elem, name, data[name]); + } + } + } + dataPriv.set(elem, 'hasDataAttrs', true); + } + } + return data; + } + if (typeof key === 'object') { + return this.each(function () { + dataUser.set(this, key); + }); + } + return access(this, function (value) { + var data; + if (elem && value === undefined) { + data = dataUser.get(elem, key); + if (data !== undefined) { + return data; + } + data = dataAttr(elem, key); + if (data !== undefined) { + return data; + } + return; + } + this.each(function () { + dataUser.set(this, key, value); + }); + }, null, value, arguments.length > 1, null, true); + }, + removeData: function (key) { + return this.each(function () { + dataUser.remove(this, key); + }); + } + }); + jQuery.extend({ + queue: function (elem, type, data) { + var queue; + if (elem) { + type = (type || 'fx') + 'queue'; + queue = dataPriv.get(elem, type); + if (data) { + if (!queue || Array.isArray(data)) { + queue = dataPriv.access(elem, type, jQuery.makeArray(data)); + } else { + queue.push(data); + } + } + return queue || []; + } + }, + dequeue: function (elem, type) { + type = type || 'fx'; + var queue = jQuery.queue(elem, type), startLength = queue.length, fn = queue.shift(), hooks = jQuery._queueHooks(elem, type), next = function () { + jQuery.dequeue(elem, type); + }; + if (fn === 'inprogress') { + fn = queue.shift(); + startLength--; + } + if (fn) { + if (type === 'fx') { + queue.unshift('inprogress'); + } + delete hooks.stop; + fn.call(elem, next, hooks); + } + if (!startLength && hooks) { + hooks.empty.fire(); + } + }, + _queueHooks: function (elem, type) { + var key = type + 'queueHooks'; + return dataPriv.get(elem, key) || dataPriv.access(elem, key, { + empty: jQuery.Callbacks('once memory').add(function () { + dataPriv.remove(elem, [ + type + 'queue', + key + ]); + }) + }); + } + }); + jQuery.fn.extend({ + queue: function (type, data) { + var setter = 2; + if (typeof type !== 'string') { + data = type; + type = 'fx'; + setter--; + } + if (arguments.length < setter) { + return jQuery.queue(this[0], type); + } + return data === undefined ? this : this.each(function () { + var queue = jQuery.queue(this, type, data); + jQuery._queueHooks(this, type); + if (type === 'fx' && queue[0] !== 'inprogress') { + jQuery.dequeue(this, type); + } + }); + }, + dequeue: function (type) { + return this.each(function () { + jQuery.dequeue(this, type); + }); + }, + clearQueue: function (type) { + return this.queue(type || 'fx', []); + }, + promise: function (type, obj) { + var tmp, count = 1, defer = jQuery.Deferred(), elements = this, i = this.length, resolve = function () { + if (!--count) { + defer.resolveWith(elements, [elements]); + } + }; + if (typeof type !== 'string') { + obj = type; + type = undefined; + } + type = type || 'fx'; + while (i--) { + tmp = dataPriv.get(elements[i], type + 'queueHooks'); + if (tmp && tmp.empty) { + count++; + tmp.empty.add(resolve); + } + } + resolve(); + return defer.promise(obj); + } + }); + var pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source; + var rcssNum = new RegExp('^(?:([+-])=|)(' + pnum + ')([a-z%]*)$', 'i'); + var cssExpand = [ + 'Top', + 'Right', + 'Bottom', + 'Left' + ]; + var isHiddenWithinTree = function (elem, el) { + elem = el || elem; + return elem.style.display === 'none' || elem.style.display === '' && jQuery.contains(elem.ownerDocument, elem) && jQuery.css(elem, 'display') === 'none'; + }; + var swap = function (elem, options, callback, args) { + var ret, name, old = {}; + for (name in options) { + old[name] = elem.style[name]; + elem.style[name] = options[name]; + } + ret = callback.apply(elem, args || []); + for (name in options) { + elem.style[name] = old[name]; + } + return ret; + }; + function adjustCSS(elem, prop, valueParts, tween) { + var adjusted, scale, maxIterations = 20, currentValue = tween ? function () { + return tween.cur(); + } : function () { + return jQuery.css(elem, prop, ''); + }, initial = currentValue(), unit = valueParts && valueParts[3] || (jQuery.cssNumber[prop] ? '' : 'px'), initialInUnit = (jQuery.cssNumber[prop] || unit !== 'px' && +initial) && rcssNum.exec(jQuery.css(elem, prop)); + if (initialInUnit && initialInUnit[3] !== unit) { + initial = initial / 2; + unit = unit || initialInUnit[3]; + initialInUnit = +initial || 1; + while (maxIterations--) { + jQuery.style(elem, prop, initialInUnit + unit); + if ((1 - scale) * (1 - (scale = currentValue() / initial || 0.5)) <= 0) { + maxIterations = 0; + } + initialInUnit = initialInUnit / scale; + } + initialInUnit = initialInUnit * 2; + jQuery.style(elem, prop, initialInUnit + unit); + valueParts = valueParts || []; + } + if (valueParts) { + initialInUnit = +initialInUnit || +initial || 0; + adjusted = valueParts[1] ? initialInUnit + (valueParts[1] + 1) * valueParts[2] : +valueParts[2]; + if (tween) { + tween.unit = unit; + tween.start = initialInUnit; + tween.end = adjusted; + } + } + return adjusted; + } + var defaultDisplayMap = {}; + function getDefaultDisplay(elem) { + var temp, doc = elem.ownerDocument, nodeName = elem.nodeName, display = defaultDisplayMap[nodeName]; + if (display) { + return display; + } + temp = doc.body.appendChild(doc.createElement(nodeName)); + display = jQuery.css(temp, 'display'); + temp.parentNode.removeChild(temp); + if (display === 'none') { + display = 'block'; + } + defaultDisplayMap[nodeName] = display; + return display; + } + function showHide(elements, show) { + var display, elem, values = [], index = 0, length = elements.length; + for (; index < length; index++) { + elem = elements[index]; + if (!elem.style) { + continue; + } + display = elem.style.display; + if (show) { + if (display === 'none') { + values[index] = dataPriv.get(elem, 'display') || null; + if (!values[index]) { + elem.style.display = ''; + } + } + if (elem.style.display === '' && isHiddenWithinTree(elem)) { + values[index] = getDefaultDisplay(elem); + } + } else { + if (display !== 'none') { + values[index] = 'none'; + dataPriv.set(elem, 'display', display); + } + } + } + for (index = 0; index < length; index++) { + if (values[index] != null) { + elements[index].style.display = values[index]; + } + } + return elements; + } + jQuery.fn.extend({ + show: function () { + return showHide(this, true); + }, + hide: function () { + return showHide(this); + }, + toggle: function (state) { + if (typeof state === 'boolean') { + return state ? this.show() : this.hide(); + } + return this.each(function () { + if (isHiddenWithinTree(this)) { + jQuery(this).show(); + } else { + jQuery(this).hide(); + } + }); + } + }); + var rcheckableType = /^(?:checkbox|radio)$/i; + var rtagName = /<([a-z][^\/\0>\x20\t\r\n\f]+)/i; + var rscriptType = /^$|^module$|\/(?:java|ecma)script/i; + var wrapMap = { + option: [ + 1, + '' + ], + thead: [ + 1, + '', + '
      ' + ], + col: [ + 2, + '', + '
      ' + ], + tr: [ + 2, + '', + '
      ' + ], + td: [ + 3, + '', + '
      ' + ], + _default: [ + 0, + '', + '' + ] + }; + wrapMap.optgroup = wrapMap.option; + wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; + wrapMap.th = wrapMap.td; + function getAll(context, tag) { + var ret; + if (typeof context.getElementsByTagName !== 'undefined') { + ret = context.getElementsByTagName(tag || '*'); + } else if (typeof context.querySelectorAll !== 'undefined') { + ret = context.querySelectorAll(tag || '*'); + } else { + ret = []; + } + if (tag === undefined || tag && nodeName(context, tag)) { + return jQuery.merge([context], ret); + } + return ret; + } + function setGlobalEval(elems, refElements) { + var i = 0, l = elems.length; + for (; i < l; i++) { + dataPriv.set(elems[i], 'globalEval', !refElements || dataPriv.get(refElements[i], 'globalEval')); + } + } + var rhtml = /<|&#?\w+;/; + function buildFragment(elems, context, scripts, selection, ignored) { + var elem, tmp, tag, wrap, contains, j, fragment = context.createDocumentFragment(), nodes = [], i = 0, l = elems.length; + for (; i < l; i++) { + elem = elems[i]; + if (elem || elem === 0) { + if (toType(elem) === 'object') { + jQuery.merge(nodes, elem.nodeType ? [elem] : elem); + } else if (!rhtml.test(elem)) { + nodes.push(context.createTextNode(elem)); + } else { + tmp = tmp || fragment.appendChild(context.createElement('div')); + tag = (rtagName.exec(elem) || [ + '', + '' + ])[1].toLowerCase(); + wrap = wrapMap[tag] || wrapMap._default; + tmp.innerHTML = wrap[1] + jQuery.htmlPrefilter(elem) + wrap[2]; + j = wrap[0]; + while (j--) { + tmp = tmp.lastChild; + } + jQuery.merge(nodes, tmp.childNodes); + tmp = fragment.firstChild; + tmp.textContent = ''; + } + } + } + fragment.textContent = ''; + i = 0; + while (elem = nodes[i++]) { + if (selection && jQuery.inArray(elem, selection) > -1) { + if (ignored) { + ignored.push(elem); + } + continue; + } + contains = jQuery.contains(elem.ownerDocument, elem); + tmp = getAll(fragment.appendChild(elem), 'script'); + if (contains) { + setGlobalEval(tmp); + } + if (scripts) { + j = 0; + while (elem = tmp[j++]) { + if (rscriptType.test(elem.type || '')) { + scripts.push(elem); + } + } + } + } + return fragment; + } + (function () { + var fragment = document.createDocumentFragment(), div = fragment.appendChild(document.createElement('div')), input = document.createElement('input'); + input.setAttribute('type', 'radio'); + input.setAttribute('checked', 'checked'); + input.setAttribute('name', 't'); + div.appendChild(input); + support.checkClone = div.cloneNode(true).cloneNode(true).lastChild.checked; + div.innerHTML = ''; + support.noCloneChecked = !!div.cloneNode(true).lastChild.defaultValue; + }()); + var documentElement = document.documentElement; + var rkeyEvent = /^key/, rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + function returnTrue() { + return true; + } + function returnFalse() { + return false; + } + function safeActiveElement() { + try { + return document.activeElement; + } catch (err) { + } + } + function on(elem, types, selector, data, fn, one) { + var origFn, type; + if (typeof types === 'object') { + if (typeof selector !== 'string') { + data = data || selector; + selector = undefined; + } + for (type in types) { + on(elem, type, selector, data, types[type], one); + } + return elem; + } + if (data == null && fn == null) { + fn = selector; + data = selector = undefined; + } else if (fn == null) { + if (typeof selector === 'string') { + fn = data; + data = undefined; + } else { + fn = data; + data = selector; + selector = undefined; + } + } + if (fn === false) { + fn = returnFalse; + } else if (!fn) { + return elem; + } + if (one === 1) { + origFn = fn; + fn = function (event) { + jQuery().off(event); + return origFn.apply(this, arguments); + }; + fn.guid = origFn.guid || (origFn.guid = jQuery.guid++); + } + return elem.each(function () { + jQuery.event.add(this, types, fn, data, selector); + }); + } + jQuery.event = { + global: {}, + add: function (elem, types, handler, data, selector) { + var handleObjIn, eventHandle, tmp, events, t, handleObj, special, handlers, type, namespaces, origType, elemData = dataPriv.get(elem); + if (!elemData) { + return; + } + if (handler.handler) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + if (selector) { + jQuery.find.matchesSelector(documentElement, selector); + } + if (!handler.guid) { + handler.guid = jQuery.guid++; + } + if (!(events = elemData.events)) { + events = elemData.events = {}; + } + if (!(eventHandle = elemData.handle)) { + eventHandle = elemData.handle = function (e) { + return typeof jQuery !== 'undefined' && jQuery.event.triggered !== e.type ? jQuery.event.dispatch.apply(elem, arguments) : undefined; + }; + } + types = (types || '').match(rnothtmlwhite) || ['']; + t = types.length; + while (t--) { + tmp = rtypenamespace.exec(types[t]) || []; + type = origType = tmp[1]; + namespaces = (tmp[2] || '').split('.').sort(); + if (!type) { + continue; + } + special = jQuery.event.special[type] || {}; + type = (selector ? special.delegateType : special.bindType) || type; + special = jQuery.event.special[type] || {}; + handleObj = jQuery.extend({ + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test(selector), + namespace: namespaces.join('.') + }, handleObjIn); + if (!(handlers = events[type])) { + handlers = events[type] = []; + handlers.delegateCount = 0; + if (!special.setup || special.setup.call(elem, data, namespaces, eventHandle) === false) { + if (elem.addEventListener) { + elem.addEventListener(type, eventHandle); + } + } + } + if (special.add) { + special.add.call(elem, handleObj); + if (!handleObj.handler.guid) { + handleObj.handler.guid = handler.guid; + } + } + if (selector) { + handlers.splice(handlers.delegateCount++, 0, handleObj); + } else { + handlers.push(handleObj); + } + jQuery.event.global[type] = true; + } + }, + remove: function (elem, types, handler, selector, mappedTypes) { + var j, origCount, tmp, events, t, handleObj, special, handlers, type, namespaces, origType, elemData = dataPriv.hasData(elem) && dataPriv.get(elem); + if (!elemData || !(events = elemData.events)) { + return; + } + types = (types || '').match(rnothtmlwhite) || ['']; + t = types.length; + while (t--) { + tmp = rtypenamespace.exec(types[t]) || []; + type = origType = tmp[1]; + namespaces = (tmp[2] || '').split('.').sort(); + if (!type) { + for (type in events) { + jQuery.event.remove(elem, type + types[t], handler, selector, true); + } + continue; + } + special = jQuery.event.special[type] || {}; + type = (selector ? special.delegateType : special.bindType) || type; + handlers = events[type] || []; + tmp = tmp[2] && new RegExp('(^|\\.)' + namespaces.join('\\.(?:.*\\.|)') + '(\\.|$)'); + origCount = j = handlers.length; + while (j--) { + handleObj = handlers[j]; + if ((mappedTypes || origType === handleObj.origType) && (!handler || handler.guid === handleObj.guid) && (!tmp || tmp.test(handleObj.namespace)) && (!selector || selector === handleObj.selector || selector === '**' && handleObj.selector)) { + handlers.splice(j, 1); + if (handleObj.selector) { + handlers.delegateCount--; + } + if (special.remove) { + special.remove.call(elem, handleObj); + } + } + } + if (origCount && !handlers.length) { + if (!special.teardown || special.teardown.call(elem, namespaces, elemData.handle) === false) { + jQuery.removeEvent(elem, type, elemData.handle); + } + delete events[type]; + } + } + if (jQuery.isEmptyObject(events)) { + dataPriv.remove(elem, 'handle events'); + } + }, + dispatch: function (nativeEvent) { + var event = jQuery.event.fix(nativeEvent); + var i, j, ret, matched, handleObj, handlerQueue, args = new Array(arguments.length), handlers = (dataPriv.get(this, 'events') || {})[event.type] || [], special = jQuery.event.special[event.type] || {}; + args[0] = event; + for (i = 1; i < arguments.length; i++) { + args[i] = arguments[i]; + } + event.delegateTarget = this; + if (special.preDispatch && special.preDispatch.call(this, event) === false) { + return; + } + handlerQueue = jQuery.event.handlers.call(this, event, handlers); + i = 0; + while ((matched = handlerQueue[i++]) && !event.isPropagationStopped()) { + event.currentTarget = matched.elem; + j = 0; + while ((handleObj = matched.handlers[j++]) && !event.isImmediatePropagationStopped()) { + if (!event.rnamespace || event.rnamespace.test(handleObj.namespace)) { + event.handleObj = handleObj; + event.data = handleObj.data; + ret = ((jQuery.event.special[handleObj.origType] || {}).handle || handleObj.handler).apply(matched.elem, args); + if (ret !== undefined) { + if ((event.result = ret) === false) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + if (special.postDispatch) { + special.postDispatch.call(this, event); + } + return event.result; + }, + handlers: function (event, handlers) { + var i, handleObj, sel, matchedHandlers, matchedSelectors, handlerQueue = [], delegateCount = handlers.delegateCount, cur = event.target; + if (delegateCount && cur.nodeType && !(event.type === 'click' && event.button >= 1)) { + for (; cur !== this; cur = cur.parentNode || this) { + if (cur.nodeType === 1 && !(event.type === 'click' && cur.disabled === true)) { + matchedHandlers = []; + matchedSelectors = {}; + for (i = 0; i < delegateCount; i++) { + handleObj = handlers[i]; + sel = handleObj.selector + ' '; + if (matchedSelectors[sel] === undefined) { + matchedSelectors[sel] = handleObj.needsContext ? jQuery(sel, this).index(cur) > -1 : jQuery.find(sel, this, null, [cur]).length; + } + if (matchedSelectors[sel]) { + matchedHandlers.push(handleObj); + } + } + if (matchedHandlers.length) { + handlerQueue.push({ + elem: cur, + handlers: matchedHandlers + }); + } + } + } + } + cur = this; + if (delegateCount < handlers.length) { + handlerQueue.push({ + elem: cur, + handlers: handlers.slice(delegateCount) + }); + } + return handlerQueue; + }, + addProp: function (name, hook) { + Object.defineProperty(jQuery.Event.prototype, name, { + enumerable: true, + configurable: true, + get: isFunction(hook) ? function () { + if (this.originalEvent) { + return hook(this.originalEvent); + } + } : function () { + if (this.originalEvent) { + return this.originalEvent[name]; + } + }, + set: function (value) { + Object.defineProperty(this, name, { + enumerable: true, + configurable: true, + writable: true, + value: value + }); + } + }); + }, + fix: function (originalEvent) { + return originalEvent[jQuery.expando] ? originalEvent : new jQuery.Event(originalEvent); + }, + special: { + load: { noBubble: true }, + focus: { + trigger: function () { + if (this !== safeActiveElement() && this.focus) { + this.focus(); + return false; + } + }, + delegateType: 'focusin' + }, + blur: { + trigger: function () { + if (this === safeActiveElement() && this.blur) { + this.blur(); + return false; + } + }, + delegateType: 'focusout' + }, + click: { + trigger: function () { + if (this.type === 'checkbox' && this.click && nodeName(this, 'input')) { + this.click(); + return false; + } + }, + _default: function (event) { + return nodeName(event.target, 'a'); + } + }, + beforeunload: { + postDispatch: function (event) { + if (event.result !== undefined && event.originalEvent) { + event.originalEvent.returnValue = event.result; + } + } + } + } + }; + jQuery.removeEvent = function (elem, type, handle) { + if (elem.removeEventListener) { + elem.removeEventListener(type, handle); + } + }; + jQuery.Event = function (src, props) { + if (!(this instanceof jQuery.Event)) { + return new jQuery.Event(src, props); + } + if (src && src.type) { + this.originalEvent = src; + this.type = src.type; + this.isDefaultPrevented = src.defaultPrevented || src.defaultPrevented === undefined && src.returnValue === false ? returnTrue : returnFalse; + this.target = src.target && src.target.nodeType === 3 ? src.target.parentNode : src.target; + this.currentTarget = src.currentTarget; + this.relatedTarget = src.relatedTarget; + } else { + this.type = src; + } + if (props) { + jQuery.extend(this, props); + } + this.timeStamp = src && src.timeStamp || Date.now(); + this[jQuery.expando] = true; + }; + jQuery.Event.prototype = { + constructor: jQuery.Event, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + isSimulated: false, + preventDefault: function () { + var e = this.originalEvent; + this.isDefaultPrevented = returnTrue; + if (e && !this.isSimulated) { + e.preventDefault(); + } + }, + stopPropagation: function () { + var e = this.originalEvent; + this.isPropagationStopped = returnTrue; + if (e && !this.isSimulated) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function () { + var e = this.originalEvent; + this.isImmediatePropagationStopped = returnTrue; + if (e && !this.isSimulated) { + e.stopImmediatePropagation(); + } + this.stopPropagation(); + } + }; + jQuery.each({ + altKey: true, + bubbles: true, + cancelable: true, + changedTouches: true, + ctrlKey: true, + detail: true, + eventPhase: true, + metaKey: true, + pageX: true, + pageY: true, + shiftKey: true, + view: true, + 'char': true, + charCode: true, + key: true, + keyCode: true, + button: true, + buttons: true, + clientX: true, + clientY: true, + offsetX: true, + offsetY: true, + pointerId: true, + pointerType: true, + screenX: true, + screenY: true, + targetTouches: true, + toElement: true, + touches: true, + which: function (event) { + var button = event.button; + if (event.which == null && rkeyEvent.test(event.type)) { + return event.charCode != null ? event.charCode : event.keyCode; + } + if (!event.which && button !== undefined && rmouseEvent.test(event.type)) { + if (button & 1) { + return 1; + } + if (button & 2) { + return 3; + } + if (button & 4) { + return 2; + } + return 0; + } + return event.which; + } + }, jQuery.event.addProp); + jQuery.each({ + mouseenter: 'mouseover', + mouseleave: 'mouseout', + pointerenter: 'pointerover', + pointerleave: 'pointerout' + }, function (orig, fix) { + jQuery.event.special[orig] = { + delegateType: fix, + bindType: fix, + handle: function (event) { + var ret, target = this, related = event.relatedTarget, handleObj = event.handleObj; + if (!related || related !== target && !jQuery.contains(target, related)) { + event.type = handleObj.origType; + ret = handleObj.handler.apply(this, arguments); + event.type = fix; + } + return ret; + } + }; + }); + jQuery.fn.extend({ + on: function (types, selector, data, fn) { + return on(this, types, selector, data, fn); + }, + one: function (types, selector, data, fn) { + return on(this, types, selector, data, fn, 1); + }, + off: function (types, selector, fn) { + var handleObj, type; + if (types && types.preventDefault && types.handleObj) { + handleObj = types.handleObj; + jQuery(types.delegateTarget).off(handleObj.namespace ? handleObj.origType + '.' + handleObj.namespace : handleObj.origType, handleObj.selector, handleObj.handler); + return this; + } + if (typeof types === 'object') { + for (type in types) { + this.off(type, selector, types[type]); + } + return this; + } + if (selector === false || typeof selector === 'function') { + fn = selector; + selector = undefined; + } + if (fn === false) { + fn = returnFalse; + } + return this.each(function () { + jQuery.event.remove(this, types, fn, selector); + }); + } + }); + var rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi, rnoInnerhtml = /\s*$/g; + function manipulationTarget(elem, content) { + if (nodeName(elem, 'table') && nodeName(content.nodeType !== 11 ? content : content.firstChild, 'tr')) { + return jQuery(elem).children('tbody')[0] || elem; + } + return elem; + } + function disableScript(elem) { + elem.type = (elem.getAttribute('type') !== null) + '/' + elem.type; + return elem; + } + function restoreScript(elem) { + if ((elem.type || '').slice(0, 5) === 'true/') { + elem.type = elem.type.slice(5); + } else { + elem.removeAttribute('type'); + } + return elem; + } + function cloneCopyEvent(src, dest) { + var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; + if (dest.nodeType !== 1) { + return; + } + if (dataPriv.hasData(src)) { + pdataOld = dataPriv.access(src); + pdataCur = dataPriv.set(dest, pdataOld); + events = pdataOld.events; + if (events) { + delete pdataCur.handle; + pdataCur.events = {}; + for (type in events) { + for (i = 0, l = events[type].length; i < l; i++) { + jQuery.event.add(dest, type, events[type][i]); + } + } + } + } + if (dataUser.hasData(src)) { + udataOld = dataUser.access(src); + udataCur = jQuery.extend({}, udataOld); + dataUser.set(dest, udataCur); + } + } + function fixInput(src, dest) { + var nodeName = dest.nodeName.toLowerCase(); + if (nodeName === 'input' && rcheckableType.test(src.type)) { + dest.checked = src.checked; + } else if (nodeName === 'input' || nodeName === 'textarea') { + dest.defaultValue = src.defaultValue; + } + } + function domManip(collection, args, callback, ignored) { + args = concat.apply([], args); + var fragment, first, scripts, hasScripts, node, doc, i = 0, l = collection.length, iNoClone = l - 1, value = args[0], valueIsFunction = isFunction(value); + if (valueIsFunction || l > 1 && typeof value === 'string' && !support.checkClone && rchecked.test(value)) { + return collection.each(function (index) { + var self = collection.eq(index); + if (valueIsFunction) { + args[0] = value.call(this, index, self.html()); + } + domManip(self, args, callback, ignored); + }); + } + if (l) { + fragment = buildFragment(args, collection[0].ownerDocument, false, collection, ignored); + first = fragment.firstChild; + if (fragment.childNodes.length === 1) { + fragment = first; + } + if (first || ignored) { + scripts = jQuery.map(getAll(fragment, 'script'), disableScript); + hasScripts = scripts.length; + for (; i < l; i++) { + node = fragment; + if (i !== iNoClone) { + node = jQuery.clone(node, true, true); + if (hasScripts) { + jQuery.merge(scripts, getAll(node, 'script')); + } + } + callback.call(collection[i], node, i); + } + if (hasScripts) { + doc = scripts[scripts.length - 1].ownerDocument; + jQuery.map(scripts, restoreScript); + for (i = 0; i < hasScripts; i++) { + node = scripts[i]; + if (rscriptType.test(node.type || '') && !dataPriv.access(node, 'globalEval') && jQuery.contains(doc, node)) { + if (node.src && (node.type || '').toLowerCase() !== 'module') { + if (jQuery._evalUrl) { + jQuery._evalUrl(node.src); + } + } else { + DOMEval(node.textContent.replace(rcleanScript, ''), doc, node); + } + } + } + } + } + } + return collection; + } + function remove(elem, selector, keepData) { + var node, nodes = selector ? jQuery.filter(selector, elem) : elem, i = 0; + for (; (node = nodes[i]) != null; i++) { + if (!keepData && node.nodeType === 1) { + jQuery.cleanData(getAll(node)); + } + if (node.parentNode) { + if (keepData && jQuery.contains(node.ownerDocument, node)) { + setGlobalEval(getAll(node, 'script')); + } + node.parentNode.removeChild(node); + } + } + return elem; + } + jQuery.extend({ + htmlPrefilter: function (html) { + return html.replace(rxhtmlTag, '<$1>'); + }, + clone: function (elem, dataAndEvents, deepDataAndEvents) { + var i, l, srcElements, destElements, clone = elem.cloneNode(true), inPage = jQuery.contains(elem.ownerDocument, elem); + if (!support.noCloneChecked && (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem)) { + destElements = getAll(clone); + srcElements = getAll(elem); + for (i = 0, l = srcElements.length; i < l; i++) { + fixInput(srcElements[i], destElements[i]); + } + } + if (dataAndEvents) { + if (deepDataAndEvents) { + srcElements = srcElements || getAll(elem); + destElements = destElements || getAll(clone); + for (i = 0, l = srcElements.length; i < l; i++) { + cloneCopyEvent(srcElements[i], destElements[i]); + } + } else { + cloneCopyEvent(elem, clone); + } + } + destElements = getAll(clone, 'script'); + if (destElements.length > 0) { + setGlobalEval(destElements, !inPage && getAll(elem, 'script')); + } + return clone; + }, + cleanData: function (elems) { + var data, elem, type, special = jQuery.event.special, i = 0; + for (; (elem = elems[i]) !== undefined; i++) { + if (acceptData(elem)) { + if (data = elem[dataPriv.expando]) { + if (data.events) { + for (type in data.events) { + if (special[type]) { + jQuery.event.remove(elem, type); + } else { + jQuery.removeEvent(elem, type, data.handle); + } + } + } + elem[dataPriv.expando] = undefined; + } + if (elem[dataUser.expando]) { + elem[dataUser.expando] = undefined; + } + } + } + } + }); + jQuery.fn.extend({ + detach: function (selector) { + return remove(this, selector, true); + }, + remove: function (selector) { + return remove(this, selector); + }, + text: function (value) { + return access(this, function (value) { + return value === undefined ? jQuery.text(this) : this.empty().each(function () { + if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) { + this.textContent = value; + } + }); + }, null, value, arguments.length); + }, + append: function () { + return domManip(this, arguments, function (elem) { + if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) { + var target = manipulationTarget(this, elem); + target.appendChild(elem); + } + }); + }, + prepend: function () { + return domManip(this, arguments, function (elem) { + if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) { + var target = manipulationTarget(this, elem); + target.insertBefore(elem, target.firstChild); + } + }); + }, + before: function () { + return domManip(this, arguments, function (elem) { + if (this.parentNode) { + this.parentNode.insertBefore(elem, this); + } + }); + }, + after: function () { + return domManip(this, arguments, function (elem) { + if (this.parentNode) { + this.parentNode.insertBefore(elem, this.nextSibling); + } + }); + }, + empty: function () { + var elem, i = 0; + for (; (elem = this[i]) != null; i++) { + if (elem.nodeType === 1) { + jQuery.cleanData(getAll(elem, false)); + elem.textContent = ''; + } + } + return this; + }, + clone: function (dataAndEvents, deepDataAndEvents) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + return this.map(function () { + return jQuery.clone(this, dataAndEvents, deepDataAndEvents); + }); + }, + html: function (value) { + return access(this, function (value) { + var elem = this[0] || {}, i = 0, l = this.length; + if (value === undefined && elem.nodeType === 1) { + return elem.innerHTML; + } + if (typeof value === 'string' && !rnoInnerhtml.test(value) && !wrapMap[(rtagName.exec(value) || [ + '', + '' + ])[1].toLowerCase()]) { + value = jQuery.htmlPrefilter(value); + try { + for (; i < l; i++) { + elem = this[i] || {}; + if (elem.nodeType === 1) { + jQuery.cleanData(getAll(elem, false)); + elem.innerHTML = value; + } + } + elem = 0; + } catch (e) { + } + } + if (elem) { + this.empty().append(value); + } + }, null, value, arguments.length); + }, + replaceWith: function () { + var ignored = []; + return domManip(this, arguments, function (elem) { + var parent = this.parentNode; + if (jQuery.inArray(this, ignored) < 0) { + jQuery.cleanData(getAll(this)); + if (parent) { + parent.replaceChild(elem, this); + } + } + }, ignored); + } + }); + jQuery.each({ + appendTo: 'append', + prependTo: 'prepend', + insertBefore: 'before', + insertAfter: 'after', + replaceAll: 'replaceWith' + }, function (name, original) { + jQuery.fn[name] = function (selector) { + var elems, ret = [], insert = jQuery(selector), last = insert.length - 1, i = 0; + for (; i <= last; i++) { + elems = i === last ? this : this.clone(true); + jQuery(insert[i])[original](elems); + push.apply(ret, elems.get()); + } + return this.pushStack(ret); + }; + }); + var rnumnonpx = new RegExp('^(' + pnum + ')(?!px)[a-z%]+$', 'i'); + var getStyles = function (elem) { + var view = elem.ownerDocument.defaultView; + if (!view || !view.opener) { + view = window; + } + return view.getComputedStyle(elem); + }; + var rboxStyle = new RegExp(cssExpand.join('|'), 'i'); + (function () { + function computeStyleTests() { + if (!div) { + return; + } + container.style.cssText = 'position:absolute;left:-11111px;width:60px;' + 'margin-top:1px;padding:0;border:0'; + div.style.cssText = 'position:relative;display:block;box-sizing:border-box;overflow:scroll;' + 'margin:auto;border:1px;padding:1px;' + 'width:60%;top:1%'; + documentElement.appendChild(container).appendChild(div); + var divStyle = window.getComputedStyle(div); + pixelPositionVal = divStyle.top !== '1%'; + reliableMarginLeftVal = roundPixelMeasures(divStyle.marginLeft) === 12; + div.style.right = '60%'; + pixelBoxStylesVal = roundPixelMeasures(divStyle.right) === 36; + boxSizingReliableVal = roundPixelMeasures(divStyle.width) === 36; + div.style.position = 'absolute'; + scrollboxSizeVal = div.offsetWidth === 36 || 'absolute'; + documentElement.removeChild(container); + div = null; + } + function roundPixelMeasures(measure) { + return Math.round(parseFloat(measure)); + } + var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, reliableMarginLeftVal, container = document.createElement('div'), div = document.createElement('div'); + if (!div.style) { + return; + } + div.style.backgroundClip = 'content-box'; + div.cloneNode(true).style.backgroundClip = ''; + support.clearCloneStyle = div.style.backgroundClip === 'content-box'; + jQuery.extend(support, { + boxSizingReliable: function () { + computeStyleTests(); + return boxSizingReliableVal; + }, + pixelBoxStyles: function () { + computeStyleTests(); + return pixelBoxStylesVal; + }, + pixelPosition: function () { + computeStyleTests(); + return pixelPositionVal; + }, + reliableMarginLeft: function () { + computeStyleTests(); + return reliableMarginLeftVal; + }, + scrollboxSize: function () { + computeStyleTests(); + return scrollboxSizeVal; + } + }); + }()); + function curCSS(elem, name, computed) { + var width, minWidth, maxWidth, ret, style = elem.style; + computed = computed || getStyles(elem); + if (computed) { + ret = computed.getPropertyValue(name) || computed[name]; + if (ret === '' && !jQuery.contains(elem.ownerDocument, elem)) { + ret = jQuery.style(elem, name); + } + if (!support.pixelBoxStyles() && rnumnonpx.test(ret) && rboxStyle.test(name)) { + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + return ret !== undefined ? ret + '' : ret; + } + function addGetHookIf(conditionFn, hookFn) { + return { + get: function () { + if (conditionFn()) { + delete this.get; + return; + } + return (this.get = hookFn).apply(this, arguments); + } + }; + } + var rdisplayswap = /^(none|table(?!-c[ea]).+)/, rcustomProp = /^--/, cssShow = { + position: 'absolute', + visibility: 'hidden', + display: 'block' + }, cssNormalTransform = { + letterSpacing: '0', + fontWeight: '400' + }, cssPrefixes = [ + 'Webkit', + 'Moz', + 'ms' + ], emptyStyle = document.createElement('div').style; + function vendorPropName(name) { + if (name in emptyStyle) { + return name; + } + var capName = name[0].toUpperCase() + name.slice(1), i = cssPrefixes.length; + while (i--) { + name = cssPrefixes[i] + capName; + if (name in emptyStyle) { + return name; + } + } + } + function finalPropName(name) { + var ret = jQuery.cssProps[name]; + if (!ret) { + ret = jQuery.cssProps[name] = vendorPropName(name) || name; + } + return ret; + } + function setPositiveNumber(elem, value, subtract) { + var matches = rcssNum.exec(value); + return matches ? Math.max(0, matches[2] - (subtract || 0)) + (matches[3] || 'px') : value; + } + function boxModelAdjustment(elem, dimension, box, isBorderBox, styles, computedVal) { + var i = dimension === 'width' ? 1 : 0, extra = 0, delta = 0; + if (box === (isBorderBox ? 'border' : 'content')) { + return 0; + } + for (; i < 4; i += 2) { + if (box === 'margin') { + delta += jQuery.css(elem, box + cssExpand[i], true, styles); + } + if (!isBorderBox) { + delta += jQuery.css(elem, 'padding' + cssExpand[i], true, styles); + if (box !== 'padding') { + delta += jQuery.css(elem, 'border' + cssExpand[i] + 'Width', true, styles); + } else { + extra += jQuery.css(elem, 'border' + cssExpand[i] + 'Width', true, styles); + } + } else { + if (box === 'content') { + delta -= jQuery.css(elem, 'padding' + cssExpand[i], true, styles); + } + if (box !== 'margin') { + delta -= jQuery.css(elem, 'border' + cssExpand[i] + 'Width', true, styles); + } + } + } + if (!isBorderBox && computedVal >= 0) { + delta += Math.max(0, Math.ceil(elem['offset' + dimension[0].toUpperCase() + dimension.slice(1)] - computedVal - delta - extra - 0.5)); + } + return delta; + } + function getWidthOrHeight(elem, dimension, extra) { + var styles = getStyles(elem), val = curCSS(elem, dimension, styles), isBorderBox = jQuery.css(elem, 'boxSizing', false, styles) === 'border-box', valueIsBorderBox = isBorderBox; + if (rnumnonpx.test(val)) { + if (!extra) { + return val; + } + val = 'auto'; + } + valueIsBorderBox = valueIsBorderBox && (support.boxSizingReliable() || val === elem.style[dimension]); + if (val === 'auto' || !parseFloat(val) && jQuery.css(elem, 'display', false, styles) === 'inline') { + val = elem['offset' + dimension[0].toUpperCase() + dimension.slice(1)]; + valueIsBorderBox = true; + } + val = parseFloat(val) || 0; + return val + boxModelAdjustment(elem, dimension, extra || (isBorderBox ? 'border' : 'content'), valueIsBorderBox, styles, val) + 'px'; + } + jQuery.extend({ + cssHooks: { + opacity: { + get: function (elem, computed) { + if (computed) { + var ret = curCSS(elem, 'opacity'); + return ret === '' ? '1' : ret; + } + } + } + }, + cssNumber: { + 'animationIterationCount': true, + 'columnCount': true, + 'fillOpacity': true, + 'flexGrow': true, + 'flexShrink': true, + 'fontWeight': true, + 'lineHeight': true, + 'opacity': true, + 'order': true, + 'orphans': true, + 'widows': true, + 'zIndex': true, + 'zoom': true + }, + cssProps: {}, + style: function (elem, name, value, extra) { + if (!elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style) { + return; + } + var ret, type, hooks, origName = camelCase(name), isCustomProp = rcustomProp.test(name), style = elem.style; + if (!isCustomProp) { + name = finalPropName(origName); + } + hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName]; + if (value !== undefined) { + type = typeof value; + if (type === 'string' && (ret = rcssNum.exec(value)) && ret[1]) { + value = adjustCSS(elem, name, ret); + type = 'number'; + } + if (value == null || value !== value) { + return; + } + if (type === 'number') { + value += ret && ret[3] || (jQuery.cssNumber[origName] ? '' : 'px'); + } + if (!support.clearCloneStyle && value === '' && name.indexOf('background') === 0) { + style[name] = 'inherit'; + } + if (!hooks || !('set' in hooks) || (value = hooks.set(elem, value, extra)) !== undefined) { + if (isCustomProp) { + style.setProperty(name, value); + } else { + style[name] = value; + } + } + } else { + if (hooks && 'get' in hooks && (ret = hooks.get(elem, false, extra)) !== undefined) { + return ret; + } + return style[name]; + } + }, + css: function (elem, name, extra, styles) { + var val, num, hooks, origName = camelCase(name), isCustomProp = rcustomProp.test(name); + if (!isCustomProp) { + name = finalPropName(origName); + } + hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName]; + if (hooks && 'get' in hooks) { + val = hooks.get(elem, true, extra); + } + if (val === undefined) { + val = curCSS(elem, name, styles); + } + if (val === 'normal' && name in cssNormalTransform) { + val = cssNormalTransform[name]; + } + if (extra === '' || extra) { + num = parseFloat(val); + return extra === true || isFinite(num) ? num || 0 : val; + } + return val; + } + }); + jQuery.each([ + 'height', + 'width' + ], function (i, dimension) { + jQuery.cssHooks[dimension] = { + get: function (elem, computed, extra) { + if (computed) { + return rdisplayswap.test(jQuery.css(elem, 'display')) && (!elem.getClientRects().length || !elem.getBoundingClientRect().width) ? swap(elem, cssShow, function () { + return getWidthOrHeight(elem, dimension, extra); + }) : getWidthOrHeight(elem, dimension, extra); + } + }, + set: function (elem, value, extra) { + var matches, styles = getStyles(elem), isBorderBox = jQuery.css(elem, 'boxSizing', false, styles) === 'border-box', subtract = extra && boxModelAdjustment(elem, dimension, extra, isBorderBox, styles); + if (isBorderBox && support.scrollboxSize() === styles.position) { + subtract -= Math.ceil(elem['offset' + dimension[0].toUpperCase() + dimension.slice(1)] - parseFloat(styles[dimension]) - boxModelAdjustment(elem, dimension, 'border', false, styles) - 0.5); + } + if (subtract && (matches = rcssNum.exec(value)) && (matches[3] || 'px') !== 'px') { + elem.style[dimension] = value; + value = jQuery.css(elem, dimension); + } + return setPositiveNumber(elem, value, subtract); + } + }; + }); + jQuery.cssHooks.marginLeft = addGetHookIf(support.reliableMarginLeft, function (elem, computed) { + if (computed) { + return (parseFloat(curCSS(elem, 'marginLeft')) || elem.getBoundingClientRect().left - swap(elem, { marginLeft: 0 }, function () { + return elem.getBoundingClientRect().left; + })) + 'px'; + } + }); + jQuery.each({ + margin: '', + padding: '', + border: 'Width' + }, function (prefix, suffix) { + jQuery.cssHooks[prefix + suffix] = { + expand: function (value) { + var i = 0, expanded = {}, parts = typeof value === 'string' ? value.split(' ') : [value]; + for (; i < 4; i++) { + expanded[prefix + cssExpand[i] + suffix] = parts[i] || parts[i - 2] || parts[0]; + } + return expanded; + } + }; + if (prefix !== 'margin') { + jQuery.cssHooks[prefix + suffix].set = setPositiveNumber; + } + }); + jQuery.fn.extend({ + css: function (name, value) { + return access(this, function (elem, name, value) { + var styles, len, map = {}, i = 0; + if (Array.isArray(name)) { + styles = getStyles(elem); + len = name.length; + for (; i < len; i++) { + map[name[i]] = jQuery.css(elem, name[i], false, styles); + } + return map; + } + return value !== undefined ? jQuery.style(elem, name, value) : jQuery.css(elem, name); + }, name, value, arguments.length > 1); + } + }); + function Tween(elem, options, prop, end, easing) { + return new Tween.prototype.init(elem, options, prop, end, easing); + } + jQuery.Tween = Tween; + Tween.prototype = { + constructor: Tween, + init: function (elem, options, prop, end, easing, unit) { + this.elem = elem; + this.prop = prop; + this.easing = easing || jQuery.easing._default; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || (jQuery.cssNumber[prop] ? '' : 'px'); + }, + cur: function () { + var hooks = Tween.propHooks[this.prop]; + return hooks && hooks.get ? hooks.get(this) : Tween.propHooks._default.get(this); + }, + run: function (percent) { + var eased, hooks = Tween.propHooks[this.prop]; + if (this.options.duration) { + this.pos = eased = jQuery.easing[this.easing](percent, this.options.duration * percent, 0, 1, this.options.duration); + } else { + this.pos = eased = percent; + } + this.now = (this.end - this.start) * eased + this.start; + if (this.options.step) { + this.options.step.call(this.elem, this.now, this); + } + if (hooks && hooks.set) { + hooks.set(this); + } else { + Tween.propHooks._default.set(this); + } + return this; + } + }; + Tween.prototype.init.prototype = Tween.prototype; + Tween.propHooks = { + _default: { + get: function (tween) { + var result; + if (tween.elem.nodeType !== 1 || tween.elem[tween.prop] != null && tween.elem.style[tween.prop] == null) { + return tween.elem[tween.prop]; + } + result = jQuery.css(tween.elem, tween.prop, ''); + return !result || result === 'auto' ? 0 : result; + }, + set: function (tween) { + if (jQuery.fx.step[tween.prop]) { + jQuery.fx.step[tween.prop](tween); + } else if (tween.elem.nodeType === 1 && (tween.elem.style[jQuery.cssProps[tween.prop]] != null || jQuery.cssHooks[tween.prop])) { + jQuery.style(tween.elem, tween.prop, tween.now + tween.unit); + } else { + tween.elem[tween.prop] = tween.now; + } + } + } + }; + Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function (tween) { + if (tween.elem.nodeType && tween.elem.parentNode) { + tween.elem[tween.prop] = tween.now; + } + } + }; + jQuery.easing = { + linear: function (p) { + return p; + }, + swing: function (p) { + return 0.5 - Math.cos(p * Math.PI) / 2; + }, + _default: 'swing' + }; + jQuery.fx = Tween.prototype.init; + jQuery.fx.step = {}; + var fxNow, inProgress, rfxtypes = /^(?:toggle|show|hide)$/, rrun = /queueHooks$/; + function schedule() { + if (inProgress) { + if (document.hidden === false && window.requestAnimationFrame) { + window.requestAnimationFrame(schedule); + } else { + window.setTimeout(schedule, jQuery.fx.interval); + } + jQuery.fx.tick(); + } + } + function createFxNow() { + window.setTimeout(function () { + fxNow = undefined; + }); + return fxNow = Date.now(); + } + function genFx(type, includeWidth) { + var which, i = 0, attrs = { height: type }; + includeWidth = includeWidth ? 1 : 0; + for (; i < 4; i += 2 - includeWidth) { + which = cssExpand[i]; + attrs['margin' + which] = attrs['padding' + which] = type; + } + if (includeWidth) { + attrs.opacity = attrs.width = type; + } + return attrs; + } + function createTween(value, prop, animation) { + var tween, collection = (Animation.tweeners[prop] || []).concat(Animation.tweeners['*']), index = 0, length = collection.length; + for (; index < length; index++) { + if (tween = collection[index].call(animation, prop, value)) { + return tween; + } + } + } + function defaultPrefilter(elem, props, opts) { + var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, isBox = 'width' in props || 'height' in props, anim = this, orig = {}, style = elem.style, hidden = elem.nodeType && isHiddenWithinTree(elem), dataShow = dataPriv.get(elem, 'fxshow'); + if (!opts.queue) { + hooks = jQuery._queueHooks(elem, 'fx'); + if (hooks.unqueued == null) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function () { + if (!hooks.unqueued) { + oldfire(); + } + }; + } + hooks.unqueued++; + anim.always(function () { + anim.always(function () { + hooks.unqueued--; + if (!jQuery.queue(elem, 'fx').length) { + hooks.empty.fire(); + } + }); + }); + } + for (prop in props) { + value = props[prop]; + if (rfxtypes.test(value)) { + delete props[prop]; + toggle = toggle || value === 'toggle'; + if (value === (hidden ? 'hide' : 'show')) { + if (value === 'show' && dataShow && dataShow[prop] !== undefined) { + hidden = true; + } else { + continue; + } + } + orig[prop] = dataShow && dataShow[prop] || jQuery.style(elem, prop); + } + } + propTween = !jQuery.isEmptyObject(props); + if (!propTween && jQuery.isEmptyObject(orig)) { + return; + } + if (isBox && elem.nodeType === 1) { + opts.overflow = [ + style.overflow, + style.overflowX, + style.overflowY + ]; + restoreDisplay = dataShow && dataShow.display; + if (restoreDisplay == null) { + restoreDisplay = dataPriv.get(elem, 'display'); + } + display = jQuery.css(elem, 'display'); + if (display === 'none') { + if (restoreDisplay) { + display = restoreDisplay; + } else { + showHide([elem], true); + restoreDisplay = elem.style.display || restoreDisplay; + display = jQuery.css(elem, 'display'); + showHide([elem]); + } + } + if (display === 'inline' || display === 'inline-block' && restoreDisplay != null) { + if (jQuery.css(elem, 'float') === 'none') { + if (!propTween) { + anim.done(function () { + style.display = restoreDisplay; + }); + if (restoreDisplay == null) { + display = style.display; + restoreDisplay = display === 'none' ? '' : display; + } + } + style.display = 'inline-block'; + } + } + } + if (opts.overflow) { + style.overflow = 'hidden'; + anim.always(function () { + style.overflow = opts.overflow[0]; + style.overflowX = opts.overflow[1]; + style.overflowY = opts.overflow[2]; + }); + } + propTween = false; + for (prop in orig) { + if (!propTween) { + if (dataShow) { + if ('hidden' in dataShow) { + hidden = dataShow.hidden; + } + } else { + dataShow = dataPriv.access(elem, 'fxshow', { display: restoreDisplay }); + } + if (toggle) { + dataShow.hidden = !hidden; + } + if (hidden) { + showHide([elem], true); + } + anim.done(function () { + if (!hidden) { + showHide([elem]); + } + dataPriv.remove(elem, 'fxshow'); + for (prop in orig) { + jQuery.style(elem, prop, orig[prop]); + } + }); + } + propTween = createTween(hidden ? dataShow[prop] : 0, prop, anim); + if (!(prop in dataShow)) { + dataShow[prop] = propTween.start; + if (hidden) { + propTween.end = propTween.start; + propTween.start = 0; + } + } + } + } + function propFilter(props, specialEasing) { + var index, name, easing, value, hooks; + for (index in props) { + name = camelCase(index); + easing = specialEasing[name]; + value = props[index]; + if (Array.isArray(value)) { + easing = value[1]; + value = props[index] = value[0]; + } + if (index !== name) { + props[name] = value; + delete props[index]; + } + hooks = jQuery.cssHooks[name]; + if (hooks && 'expand' in hooks) { + value = hooks.expand(value); + delete props[name]; + for (index in value) { + if (!(index in props)) { + props[index] = value[index]; + specialEasing[index] = easing; + } + } + } else { + specialEasing[name] = easing; + } + } + } + function Animation(elem, properties, options) { + var result, stopped, index = 0, length = Animation.prefilters.length, deferred = jQuery.Deferred().always(function () { + delete tick.elem; + }), tick = function () { + if (stopped) { + return false; + } + var currentTime = fxNow || createFxNow(), remaining = Math.max(0, animation.startTime + animation.duration - currentTime), temp = remaining / animation.duration || 0, percent = 1 - temp, index = 0, length = animation.tweens.length; + for (; index < length; index++) { + animation.tweens[index].run(percent); + } + deferred.notifyWith(elem, [ + animation, + percent, + remaining + ]); + if (percent < 1 && length) { + return remaining; + } + if (!length) { + deferred.notifyWith(elem, [ + animation, + 1, + 0 + ]); + } + deferred.resolveWith(elem, [animation]); + return false; + }, animation = deferred.promise({ + elem: elem, + props: jQuery.extend({}, properties), + opts: jQuery.extend(true, { + specialEasing: {}, + easing: jQuery.easing._default + }, options), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function (prop, end) { + var tween = jQuery.Tween(elem, animation.opts, prop, end, animation.opts.specialEasing[prop] || animation.opts.easing); + animation.tweens.push(tween); + return tween; + }, + stop: function (gotoEnd) { + var index = 0, length = gotoEnd ? animation.tweens.length : 0; + if (stopped) { + return this; + } + stopped = true; + for (; index < length; index++) { + animation.tweens[index].run(1); + } + if (gotoEnd) { + deferred.notifyWith(elem, [ + animation, + 1, + 0 + ]); + deferred.resolveWith(elem, [ + animation, + gotoEnd + ]); + } else { + deferred.rejectWith(elem, [ + animation, + gotoEnd + ]); + } + return this; + } + }), props = animation.props; + propFilter(props, animation.opts.specialEasing); + for (; index < length; index++) { + result = Animation.prefilters[index].call(animation, elem, props, animation.opts); + if (result) { + if (isFunction(result.stop)) { + jQuery._queueHooks(animation.elem, animation.opts.queue).stop = result.stop.bind(result); + } + return result; + } + } + jQuery.map(props, createTween, animation); + if (isFunction(animation.opts.start)) { + animation.opts.start.call(elem, animation); + } + animation.progress(animation.opts.progress).done(animation.opts.done, animation.opts.complete).fail(animation.opts.fail).always(animation.opts.always); + jQuery.fx.timer(jQuery.extend(tick, { + elem: elem, + anim: animation, + queue: animation.opts.queue + })); + return animation; + } + jQuery.Animation = jQuery.extend(Animation, { + tweeners: { + '*': [function (prop, value) { + var tween = this.createTween(prop, value); + adjustCSS(tween.elem, prop, rcssNum.exec(value), tween); + return tween; + }] + }, + tweener: function (props, callback) { + if (isFunction(props)) { + callback = props; + props = ['*']; + } else { + props = props.match(rnothtmlwhite); + } + var prop, index = 0, length = props.length; + for (; index < length; index++) { + prop = props[index]; + Animation.tweeners[prop] = Animation.tweeners[prop] || []; + Animation.tweeners[prop].unshift(callback); + } + }, + prefilters: [defaultPrefilter], + prefilter: function (callback, prepend) { + if (prepend) { + Animation.prefilters.unshift(callback); + } else { + Animation.prefilters.push(callback); + } + } + }); + jQuery.speed = function (speed, easing, fn) { + var opt = speed && typeof speed === 'object' ? jQuery.extend({}, speed) : { + complete: fn || !fn && easing || isFunction(speed) && speed, + duration: speed, + easing: fn && easing || easing && !isFunction(easing) && easing + }; + if (jQuery.fx.off) { + opt.duration = 0; + } else { + if (typeof opt.duration !== 'number') { + if (opt.duration in jQuery.fx.speeds) { + opt.duration = jQuery.fx.speeds[opt.duration]; + } else { + opt.duration = jQuery.fx.speeds._default; + } + } + } + if (opt.queue == null || opt.queue === true) { + opt.queue = 'fx'; + } + opt.old = opt.complete; + opt.complete = function () { + if (isFunction(opt.old)) { + opt.old.call(this); + } + if (opt.queue) { + jQuery.dequeue(this, opt.queue); + } + }; + return opt; + }; + jQuery.fn.extend({ + fadeTo: function (speed, to, easing, callback) { + return this.filter(isHiddenWithinTree).css('opacity', 0).show().end().animate({ opacity: to }, speed, easing, callback); + }, + animate: function (prop, speed, easing, callback) { + var empty = jQuery.isEmptyObject(prop), optall = jQuery.speed(speed, easing, callback), doAnimation = function () { + var anim = Animation(this, jQuery.extend({}, prop), optall); + if (empty || dataPriv.get(this, 'finish')) { + anim.stop(true); + } + }; + doAnimation.finish = doAnimation; + return empty || optall.queue === false ? this.each(doAnimation) : this.queue(optall.queue, doAnimation); + }, + stop: function (type, clearQueue, gotoEnd) { + var stopQueue = function (hooks) { + var stop = hooks.stop; + delete hooks.stop; + stop(gotoEnd); + }; + if (typeof type !== 'string') { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if (clearQueue && type !== false) { + this.queue(type || 'fx', []); + } + return this.each(function () { + var dequeue = true, index = type != null && type + 'queueHooks', timers = jQuery.timers, data = dataPriv.get(this); + if (index) { + if (data[index] && data[index].stop) { + stopQueue(data[index]); + } + } else { + for (index in data) { + if (data[index] && data[index].stop && rrun.test(index)) { + stopQueue(data[index]); + } + } + } + for (index = timers.length; index--;) { + if (timers[index].elem === this && (type == null || timers[index].queue === type)) { + timers[index].anim.stop(gotoEnd); + dequeue = false; + timers.splice(index, 1); + } + } + if (dequeue || !gotoEnd) { + jQuery.dequeue(this, type); + } + }); + }, + finish: function (type) { + if (type !== false) { + type = type || 'fx'; + } + return this.each(function () { + var index, data = dataPriv.get(this), queue = data[type + 'queue'], hooks = data[type + 'queueHooks'], timers = jQuery.timers, length = queue ? queue.length : 0; + data.finish = true; + jQuery.queue(this, type, []); + if (hooks && hooks.stop) { + hooks.stop.call(this, true); + } + for (index = timers.length; index--;) { + if (timers[index].elem === this && timers[index].queue === type) { + timers[index].anim.stop(true); + timers.splice(index, 1); + } + } + for (index = 0; index < length; index++) { + if (queue[index] && queue[index].finish) { + queue[index].finish.call(this); + } + } + delete data.finish; + }); + } + }); + jQuery.each([ + 'toggle', + 'show', + 'hide' + ], function (i, name) { + var cssFn = jQuery.fn[name]; + jQuery.fn[name] = function (speed, easing, callback) { + return speed == null || typeof speed === 'boolean' ? cssFn.apply(this, arguments) : this.animate(genFx(name, true), speed, easing, callback); + }; + }); + jQuery.each({ + slideDown: genFx('show'), + slideUp: genFx('hide'), + slideToggle: genFx('toggle'), + fadeIn: { opacity: 'show' }, + fadeOut: { opacity: 'hide' }, + fadeToggle: { opacity: 'toggle' } + }, function (name, props) { + jQuery.fn[name] = function (speed, easing, callback) { + return this.animate(props, speed, easing, callback); + }; + }); + jQuery.timers = []; + jQuery.fx.tick = function () { + var timer, i = 0, timers = jQuery.timers; + fxNow = Date.now(); + for (; i < timers.length; i++) { + timer = timers[i]; + if (!timer() && timers[i] === timer) { + timers.splice(i--, 1); + } + } + if (!timers.length) { + jQuery.fx.stop(); + } + fxNow = undefined; + }; + jQuery.fx.timer = function (timer) { + jQuery.timers.push(timer); + jQuery.fx.start(); + }; + jQuery.fx.interval = 13; + jQuery.fx.start = function () { + if (inProgress) { + return; + } + inProgress = true; + schedule(); + }; + jQuery.fx.stop = function () { + inProgress = null; + }; + jQuery.fx.speeds = { + slow: 600, + fast: 200, + _default: 400 + }; + jQuery.fn.delay = function (time, type) { + time = jQuery.fx ? jQuery.fx.speeds[time] || time : time; + type = type || 'fx'; + return this.queue(type, function (next, hooks) { + var timeout = window.setTimeout(next, time); + hooks.stop = function () { + window.clearTimeout(timeout); + }; + }); + }; + (function () { + var input = document.createElement('input'), select = document.createElement('select'), opt = select.appendChild(document.createElement('option')); + input.type = 'checkbox'; + support.checkOn = input.value !== ''; + support.optSelected = opt.selected; + input = document.createElement('input'); + input.value = 't'; + input.type = 'radio'; + support.radioValue = input.value === 't'; + }()); + var boolHook, attrHandle = jQuery.expr.attrHandle; + jQuery.fn.extend({ + attr: function (name, value) { + return access(this, jQuery.attr, name, value, arguments.length > 1); + }, + removeAttr: function (name) { + return this.each(function () { + jQuery.removeAttr(this, name); + }); + } + }); + jQuery.extend({ + attr: function (elem, name, value) { + var ret, hooks, nType = elem.nodeType; + if (nType === 3 || nType === 8 || nType === 2) { + return; + } + if (typeof elem.getAttribute === 'undefined') { + return jQuery.prop(elem, name, value); + } + if (nType !== 1 || !jQuery.isXMLDoc(elem)) { + hooks = jQuery.attrHooks[name.toLowerCase()] || (jQuery.expr.match.bool.test(name) ? boolHook : undefined); + } + if (value !== undefined) { + if (value === null) { + jQuery.removeAttr(elem, name); + return; + } + if (hooks && 'set' in hooks && (ret = hooks.set(elem, value, name)) !== undefined) { + return ret; + } + elem.setAttribute(name, value + ''); + return value; + } + if (hooks && 'get' in hooks && (ret = hooks.get(elem, name)) !== null) { + return ret; + } + ret = jQuery.find.attr(elem, name); + return ret == null ? undefined : ret; + }, + attrHooks: { + type: { + set: function (elem, value) { + if (!support.radioValue && value === 'radio' && nodeName(elem, 'input')) { + var val = elem.value; + elem.setAttribute('type', value); + if (val) { + elem.value = val; + } + return value; + } + } + } + }, + removeAttr: function (elem, value) { + var name, i = 0, attrNames = value && value.match(rnothtmlwhite); + if (attrNames && elem.nodeType === 1) { + while (name = attrNames[i++]) { + elem.removeAttribute(name); + } + } + } + }); + boolHook = { + set: function (elem, value, name) { + if (value === false) { + jQuery.removeAttr(elem, name); + } else { + elem.setAttribute(name, name); + } + return name; + } + }; + jQuery.each(jQuery.expr.match.bool.source.match(/\w+/g), function (i, name) { + var getter = attrHandle[name] || jQuery.find.attr; + attrHandle[name] = function (elem, name, isXML) { + var ret, handle, lowercaseName = name.toLowerCase(); + if (!isXML) { + handle = attrHandle[lowercaseName]; + attrHandle[lowercaseName] = ret; + ret = getter(elem, name, isXML) != null ? lowercaseName : null; + attrHandle[lowercaseName] = handle; + } + return ret; + }; + }); + var rfocusable = /^(?:input|select|textarea|button)$/i, rclickable = /^(?:a|area)$/i; + jQuery.fn.extend({ + prop: function (name, value) { + return access(this, jQuery.prop, name, value, arguments.length > 1); + }, + removeProp: function (name) { + return this.each(function () { + delete this[jQuery.propFix[name] || name]; + }); + } + }); + jQuery.extend({ + prop: function (elem, name, value) { + var ret, hooks, nType = elem.nodeType; + if (nType === 3 || nType === 8 || nType === 2) { + return; + } + if (nType !== 1 || !jQuery.isXMLDoc(elem)) { + name = jQuery.propFix[name] || name; + hooks = jQuery.propHooks[name]; + } + if (value !== undefined) { + if (hooks && 'set' in hooks && (ret = hooks.set(elem, value, name)) !== undefined) { + return ret; + } + return elem[name] = value; + } + if (hooks && 'get' in hooks && (ret = hooks.get(elem, name)) !== null) { + return ret; + } + return elem[name]; + }, + propHooks: { + tabIndex: { + get: function (elem) { + var tabindex = jQuery.find.attr(elem, 'tabindex'); + if (tabindex) { + return parseInt(tabindex, 10); + } + if (rfocusable.test(elem.nodeName) || rclickable.test(elem.nodeName) && elem.href) { + return 0; + } + return -1; + } + } + }, + propFix: { + 'for': 'htmlFor', + 'class': 'className' + } + }); + if (!support.optSelected) { + jQuery.propHooks.selected = { + get: function (elem) { + var parent = elem.parentNode; + if (parent && parent.parentNode) { + parent.parentNode.selectedIndex; + } + return null; + }, + set: function (elem) { + var parent = elem.parentNode; + if (parent) { + parent.selectedIndex; + if (parent.parentNode) { + parent.parentNode.selectedIndex; + } + } + } + }; + } + jQuery.each([ + 'tabIndex', + 'readOnly', + 'maxLength', + 'cellSpacing', + 'cellPadding', + 'rowSpan', + 'colSpan', + 'useMap', + 'frameBorder', + 'contentEditable' + ], function () { + jQuery.propFix[this.toLowerCase()] = this; + }); + function stripAndCollapse(value) { + var tokens = value.match(rnothtmlwhite) || []; + return tokens.join(' '); + } + function getClass(elem) { + return elem.getAttribute && elem.getAttribute('class') || ''; + } + function classesToArray(value) { + if (Array.isArray(value)) { + return value; + } + if (typeof value === 'string') { + return value.match(rnothtmlwhite) || []; + } + return []; + } + jQuery.fn.extend({ + addClass: function (value) { + var classes, elem, cur, curValue, clazz, j, finalValue, i = 0; + if (isFunction(value)) { + return this.each(function (j) { + jQuery(this).addClass(value.call(this, j, getClass(this))); + }); + } + classes = classesToArray(value); + if (classes.length) { + while (elem = this[i++]) { + curValue = getClass(elem); + cur = elem.nodeType === 1 && ' ' + stripAndCollapse(curValue) + ' '; + if (cur) { + j = 0; + while (clazz = classes[j++]) { + if (cur.indexOf(' ' + clazz + ' ') < 0) { + cur += clazz + ' '; + } + } + finalValue = stripAndCollapse(cur); + if (curValue !== finalValue) { + elem.setAttribute('class', finalValue); + } + } + } + } + return this; + }, + removeClass: function (value) { + var classes, elem, cur, curValue, clazz, j, finalValue, i = 0; + if (isFunction(value)) { + return this.each(function (j) { + jQuery(this).removeClass(value.call(this, j, getClass(this))); + }); + } + if (!arguments.length) { + return this.attr('class', ''); + } + classes = classesToArray(value); + if (classes.length) { + while (elem = this[i++]) { + curValue = getClass(elem); + cur = elem.nodeType === 1 && ' ' + stripAndCollapse(curValue) + ' '; + if (cur) { + j = 0; + while (clazz = classes[j++]) { + while (cur.indexOf(' ' + clazz + ' ') > -1) { + cur = cur.replace(' ' + clazz + ' ', ' '); + } + } + finalValue = stripAndCollapse(cur); + if (curValue !== finalValue) { + elem.setAttribute('class', finalValue); + } + } + } + } + return this; + }, + toggleClass: function (value, stateVal) { + var type = typeof value, isValidValue = type === 'string' || Array.isArray(value); + if (typeof stateVal === 'boolean' && isValidValue) { + return stateVal ? this.addClass(value) : this.removeClass(value); + } + if (isFunction(value)) { + return this.each(function (i) { + jQuery(this).toggleClass(value.call(this, i, getClass(this), stateVal), stateVal); + }); + } + return this.each(function () { + var className, i, self, classNames; + if (isValidValue) { + i = 0; + self = jQuery(this); + classNames = classesToArray(value); + while (className = classNames[i++]) { + if (self.hasClass(className)) { + self.removeClass(className); + } else { + self.addClass(className); + } + } + } else if (value === undefined || type === 'boolean') { + className = getClass(this); + if (className) { + dataPriv.set(this, '__className__', className); + } + if (this.setAttribute) { + this.setAttribute('class', className || value === false ? '' : dataPriv.get(this, '__className__') || ''); + } + } + }); + }, + hasClass: function (selector) { + var className, elem, i = 0; + className = ' ' + selector + ' '; + while (elem = this[i++]) { + if (elem.nodeType === 1 && (' ' + stripAndCollapse(getClass(elem)) + ' ').indexOf(className) > -1) { + return true; + } + } + return false; + } + }); + var rreturn = /\r/g; + jQuery.fn.extend({ + val: function (value) { + var hooks, ret, valueIsFunction, elem = this[0]; + if (!arguments.length) { + if (elem) { + hooks = jQuery.valHooks[elem.type] || jQuery.valHooks[elem.nodeName.toLowerCase()]; + if (hooks && 'get' in hooks && (ret = hooks.get(elem, 'value')) !== undefined) { + return ret; + } + ret = elem.value; + if (typeof ret === 'string') { + return ret.replace(rreturn, ''); + } + return ret == null ? '' : ret; + } + return; + } + valueIsFunction = isFunction(value); + return this.each(function (i) { + var val; + if (this.nodeType !== 1) { + return; + } + if (valueIsFunction) { + val = value.call(this, i, jQuery(this).val()); + } else { + val = value; + } + if (val == null) { + val = ''; + } else if (typeof val === 'number') { + val += ''; + } else if (Array.isArray(val)) { + val = jQuery.map(val, function (value) { + return value == null ? '' : value + ''; + }); + } + hooks = jQuery.valHooks[this.type] || jQuery.valHooks[this.nodeName.toLowerCase()]; + if (!hooks || !('set' in hooks) || hooks.set(this, val, 'value') === undefined) { + this.value = val; + } + }); + } + }); + jQuery.extend({ + valHooks: { + option: { + get: function (elem) { + var val = jQuery.find.attr(elem, 'value'); + return val != null ? val : stripAndCollapse(jQuery.text(elem)); + } + }, + select: { + get: function (elem) { + var value, option, i, options = elem.options, index = elem.selectedIndex, one = elem.type === 'select-one', values = one ? null : [], max = one ? index + 1 : options.length; + if (index < 0) { + i = max; + } else { + i = one ? index : 0; + } + for (; i < max; i++) { + option = options[i]; + if ((option.selected || i === index) && !option.disabled && (!option.parentNode.disabled || !nodeName(option.parentNode, 'optgroup'))) { + value = jQuery(option).val(); + if (one) { + return value; + } + values.push(value); + } + } + return values; + }, + set: function (elem, value) { + var optionSet, option, options = elem.options, values = jQuery.makeArray(value), i = options.length; + while (i--) { + option = options[i]; + if (option.selected = jQuery.inArray(jQuery.valHooks.option.get(option), values) > -1) { + optionSet = true; + } + } + if (!optionSet) { + elem.selectedIndex = -1; + } + return values; + } + } + } + }); + jQuery.each([ + 'radio', + 'checkbox' + ], function () { + jQuery.valHooks[this] = { + set: function (elem, value) { + if (Array.isArray(value)) { + return elem.checked = jQuery.inArray(jQuery(elem).val(), value) > -1; + } + } + }; + if (!support.checkOn) { + jQuery.valHooks[this].get = function (elem) { + return elem.getAttribute('value') === null ? 'on' : elem.value; + }; + } + }); + support.focusin = 'onfocusin' in window; + var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, stopPropagationCallback = function (e) { + e.stopPropagation(); + }; + jQuery.extend(jQuery.event, { + trigger: function (event, data, elem, onlyHandlers) { + var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, eventPath = [elem || document], type = hasOwn.call(event, 'type') ? event.type : event, namespaces = hasOwn.call(event, 'namespace') ? event.namespace.split('.') : []; + cur = lastElement = tmp = elem = elem || document; + if (elem.nodeType === 3 || elem.nodeType === 8) { + return; + } + if (rfocusMorph.test(type + jQuery.event.triggered)) { + return; + } + if (type.indexOf('.') > -1) { + namespaces = type.split('.'); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf(':') < 0 && 'on' + type; + event = event[jQuery.expando] ? event : new jQuery.Event(type, typeof event === 'object' && event); + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join('.'); + event.rnamespace = event.namespace ? new RegExp('(^|\\.)' + namespaces.join('\\.(?:.*\\.|)') + '(\\.|$)') : null; + event.result = undefined; + if (!event.target) { + event.target = elem; + } + data = data == null ? [event] : jQuery.makeArray(data, [event]); + special = jQuery.event.special[type] || {}; + if (!onlyHandlers && special.trigger && special.trigger.apply(elem, data) === false) { + return; + } + if (!onlyHandlers && !special.noBubble && !isWindow(elem)) { + bubbleType = special.delegateType || type; + if (!rfocusMorph.test(bubbleType + type)) { + cur = cur.parentNode; + } + for (; cur; cur = cur.parentNode) { + eventPath.push(cur); + tmp = cur; + } + if (tmp === (elem.ownerDocument || document)) { + eventPath.push(tmp.defaultView || tmp.parentWindow || window); + } + } + i = 0; + while ((cur = eventPath[i++]) && !event.isPropagationStopped()) { + lastElement = cur; + event.type = i > 1 ? bubbleType : special.bindType || type; + handle = (dataPriv.get(cur, 'events') || {})[event.type] && dataPriv.get(cur, 'handle'); + if (handle) { + handle.apply(cur, data); + } + handle = ontype && cur[ontype]; + if (handle && handle.apply && acceptData(cur)) { + event.result = handle.apply(cur, data); + if (event.result === false) { + event.preventDefault(); + } + } + } + event.type = type; + if (!onlyHandlers && !event.isDefaultPrevented()) { + if ((!special._default || special._default.apply(eventPath.pop(), data) === false) && acceptData(elem)) { + if (ontype && isFunction(elem[type]) && !isWindow(elem)) { + tmp = elem[ontype]; + if (tmp) { + elem[ontype] = null; + } + jQuery.event.triggered = type; + if (event.isPropagationStopped()) { + lastElement.addEventListener(type, stopPropagationCallback); + } + elem[type](); + if (event.isPropagationStopped()) { + lastElement.removeEventListener(type, stopPropagationCallback); + } + jQuery.event.triggered = undefined; + if (tmp) { + elem[ontype] = tmp; + } + } + } + } + return event.result; + }, + simulate: function (type, elem, event) { + var e = jQuery.extend(new jQuery.Event(), event, { + type: type, + isSimulated: true + }); + jQuery.event.trigger(e, null, elem); + } + }); + jQuery.fn.extend({ + trigger: function (type, data) { + return this.each(function () { + jQuery.event.trigger(type, data, this); + }); + }, + triggerHandler: function (type, data) { + var elem = this[0]; + if (elem) { + return jQuery.event.trigger(type, data, elem, true); + } + } + }); + if (!support.focusin) { + jQuery.each({ + focus: 'focusin', + blur: 'focusout' + }, function (orig, fix) { + var handler = function (event) { + jQuery.event.simulate(fix, event.target, jQuery.event.fix(event)); + }; + jQuery.event.special[fix] = { + setup: function () { + var doc = this.ownerDocument || this, attaches = dataPriv.access(doc, fix); + if (!attaches) { + doc.addEventListener(orig, handler, true); + } + dataPriv.access(doc, fix, (attaches || 0) + 1); + }, + teardown: function () { + var doc = this.ownerDocument || this, attaches = dataPriv.access(doc, fix) - 1; + if (!attaches) { + doc.removeEventListener(orig, handler, true); + dataPriv.remove(doc, fix); + } else { + dataPriv.access(doc, fix, attaches); + } + } + }; + }); + } + var location = window.location; + var nonce = Date.now(); + var rquery = /\?/; + jQuery.parseXML = function (data) { + var xml; + if (!data || typeof data !== 'string') { + return null; + } + try { + xml = new window.DOMParser().parseFromString(data, 'text/xml'); + } catch (e) { + xml = undefined; + } + if (!xml || xml.getElementsByTagName('parsererror').length) { + jQuery.error('Invalid XML: ' + data); + } + return xml; + }; + var rbracket = /\[\]$/, rCRLF = /\r?\n/g, rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, rsubmittable = /^(?:input|select|textarea|keygen)/i; + function buildParams(prefix, obj, traditional, add) { + var name; + if (Array.isArray(obj)) { + jQuery.each(obj, function (i, v) { + if (traditional || rbracket.test(prefix)) { + add(prefix, v); + } else { + buildParams(prefix + '[' + (typeof v === 'object' && v != null ? i : '') + ']', v, traditional, add); + } + }); + } else if (!traditional && toType(obj) === 'object') { + for (name in obj) { + buildParams(prefix + '[' + name + ']', obj[name], traditional, add); + } + } else { + add(prefix, obj); + } + } + jQuery.param = function (a, traditional) { + var prefix, s = [], add = function (key, valueOrFunction) { + var value = isFunction(valueOrFunction) ? valueOrFunction() : valueOrFunction; + s[s.length] = encodeURIComponent(key) + '=' + encodeURIComponent(value == null ? '' : value); + }; + if (Array.isArray(a) || a.jquery && !jQuery.isPlainObject(a)) { + jQuery.each(a, function () { + add(this.name, this.value); + }); + } else { + for (prefix in a) { + buildParams(prefix, a[prefix], traditional, add); + } + } + return s.join('&'); + }; + jQuery.fn.extend({ + serialize: function () { + return jQuery.param(this.serializeArray()); + }, + serializeArray: function () { + return this.map(function () { + var elements = jQuery.prop(this, 'elements'); + return elements ? jQuery.makeArray(elements) : this; + }).filter(function () { + var type = this.type; + return this.name && !jQuery(this).is(':disabled') && rsubmittable.test(this.nodeName) && !rsubmitterTypes.test(type) && (this.checked || !rcheckableType.test(type)); + }).map(function (i, elem) { + var val = jQuery(this).val(); + if (val == null) { + return null; + } + if (Array.isArray(val)) { + return jQuery.map(val, function (val) { + return { + name: elem.name, + value: val.replace(rCRLF, '\r\n') + }; + }); + } + return { + name: elem.name, + value: val.replace(rCRLF, '\r\n') + }; + }).get(); + } + }); + var r20 = /%20/g, rhash = /#.*$/, rantiCache = /([?&])_=[^&]*/, rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, rnoContent = /^(?:GET|HEAD)$/, rprotocol = /^\/\//, prefilters = {}, transports = {}, allTypes = '*/'.concat('*'), originAnchor = document.createElement('a'); + originAnchor.href = location.href; + function addToPrefiltersOrTransports(structure) { + return function (dataTypeExpression, func) { + if (typeof dataTypeExpression !== 'string') { + func = dataTypeExpression; + dataTypeExpression = '*'; + } + var dataType, i = 0, dataTypes = dataTypeExpression.toLowerCase().match(rnothtmlwhite) || []; + if (isFunction(func)) { + while (dataType = dataTypes[i++]) { + if (dataType[0] === '+') { + dataType = dataType.slice(1) || '*'; + (structure[dataType] = structure[dataType] || []).unshift(func); + } else { + (structure[dataType] = structure[dataType] || []).push(func); + } + } + } + }; + } + function inspectPrefiltersOrTransports(structure, options, originalOptions, jqXHR) { + var inspected = {}, seekingTransport = structure === transports; + function inspect(dataType) { + var selected; + inspected[dataType] = true; + jQuery.each(structure[dataType] || [], function (_, prefilterOrFactory) { + var dataTypeOrTransport = prefilterOrFactory(options, originalOptions, jqXHR); + if (typeof dataTypeOrTransport === 'string' && !seekingTransport && !inspected[dataTypeOrTransport]) { + options.dataTypes.unshift(dataTypeOrTransport); + inspect(dataTypeOrTransport); + return false; + } else if (seekingTransport) { + return !(selected = dataTypeOrTransport); + } + }); + return selected; + } + return inspect(options.dataTypes[0]) || !inspected['*'] && inspect('*'); + } + function ajaxExtend(target, src) { + var key, deep, flatOptions = jQuery.ajaxSettings.flatOptions || {}; + for (key in src) { + if (src[key] !== undefined) { + (flatOptions[key] ? target : deep || (deep = {}))[key] = src[key]; + } + } + if (deep) { + jQuery.extend(true, target, deep); + } + return target; + } + function ajaxHandleResponses(s, jqXHR, responses) { + var ct, type, finalDataType, firstDataType, contents = s.contents, dataTypes = s.dataTypes; + while (dataTypes[0] === '*') { + dataTypes.shift(); + if (ct === undefined) { + ct = s.mimeType || jqXHR.getResponseHeader('Content-Type'); + } + } + if (ct) { + for (type in contents) { + if (contents[type] && contents[type].test(ct)) { + dataTypes.unshift(type); + break; + } + } + } + if (dataTypes[0] in responses) { + finalDataType = dataTypes[0]; + } else { + for (type in responses) { + if (!dataTypes[0] || s.converters[type + ' ' + dataTypes[0]]) { + finalDataType = type; + break; + } + if (!firstDataType) { + firstDataType = type; + } + } + finalDataType = finalDataType || firstDataType; + } + if (finalDataType) { + if (finalDataType !== dataTypes[0]) { + dataTypes.unshift(finalDataType); + } + return responses[finalDataType]; + } + } + function ajaxConvert(s, response, jqXHR, isSuccess) { + var conv2, current, conv, tmp, prev, converters = {}, dataTypes = s.dataTypes.slice(); + if (dataTypes[1]) { + for (conv in s.converters) { + converters[conv.toLowerCase()] = s.converters[conv]; + } + } + current = dataTypes.shift(); + while (current) { + if (s.responseFields[current]) { + jqXHR[s.responseFields[current]] = response; + } + if (!prev && isSuccess && s.dataFilter) { + response = s.dataFilter(response, s.dataType); + } + prev = current; + current = dataTypes.shift(); + if (current) { + if (current === '*') { + current = prev; + } else if (prev !== '*' && prev !== current) { + conv = converters[prev + ' ' + current] || converters['* ' + current]; + if (!conv) { + for (conv2 in converters) { + tmp = conv2.split(' '); + if (tmp[1] === current) { + conv = converters[prev + ' ' + tmp[0]] || converters['* ' + tmp[0]]; + if (conv) { + if (conv === true) { + conv = converters[conv2]; + } else if (converters[conv2] !== true) { + current = tmp[0]; + dataTypes.unshift(tmp[1]); + } + break; + } + } + } + } + if (conv !== true) { + if (conv && s.throws) { + response = conv(response); + } else { + try { + response = conv(response); + } catch (e) { + return { + state: 'parsererror', + error: conv ? e : 'No conversion from ' + prev + ' to ' + current + }; + } + } + } + } + } + } + return { + state: 'success', + data: response + }; + } + jQuery.extend({ + active: 0, + lastModified: {}, + etag: {}, + ajaxSettings: { + url: location.href, + type: 'GET', + isLocal: rlocalProtocol.test(location.protocol), + global: true, + processData: true, + async: true, + contentType: 'application/x-www-form-urlencoded; charset=UTF-8', + accepts: { + '*': allTypes, + text: 'text/plain', + html: 'text/html', + xml: 'application/xml, text/xml', + json: 'application/json, text/javascript' + }, + contents: { + xml: /\bxml\b/, + html: /\bhtml/, + json: /\bjson\b/ + }, + responseFields: { + xml: 'responseXML', + text: 'responseText', + json: 'responseJSON' + }, + converters: { + '* text': String, + 'text html': true, + 'text json': JSON.parse, + 'text xml': jQuery.parseXML + }, + flatOptions: { + url: true, + context: true + } + }, + ajaxSetup: function (target, settings) { + return settings ? ajaxExtend(ajaxExtend(target, jQuery.ajaxSettings), settings) : ajaxExtend(jQuery.ajaxSettings, target); + }, + ajaxPrefilter: addToPrefiltersOrTransports(prefilters), + ajaxTransport: addToPrefiltersOrTransports(transports), + ajax: function (url, options) { + if (typeof url === 'object') { + options = url; + url = undefined; + } + options = options || {}; + var transport, cacheURL, responseHeadersString, responseHeaders, timeoutTimer, urlAnchor, completed, fireGlobals, i, uncached, s = jQuery.ajaxSetup({}, options), callbackContext = s.context || s, globalEventContext = s.context && (callbackContext.nodeType || callbackContext.jquery) ? jQuery(callbackContext) : jQuery.event, deferred = jQuery.Deferred(), completeDeferred = jQuery.Callbacks('once memory'), statusCode = s.statusCode || {}, requestHeaders = {}, requestHeadersNames = {}, strAbort = 'canceled', jqXHR = { + readyState: 0, + getResponseHeader: function (key) { + var match; + if (completed) { + if (!responseHeaders) { + responseHeaders = {}; + while (match = rheaders.exec(responseHeadersString)) { + responseHeaders[match[1].toLowerCase()] = match[2]; + } + } + match = responseHeaders[key.toLowerCase()]; + } + return match == null ? null : match; + }, + getAllResponseHeaders: function () { + return completed ? responseHeadersString : null; + }, + setRequestHeader: function (name, value) { + if (completed == null) { + name = requestHeadersNames[name.toLowerCase()] = requestHeadersNames[name.toLowerCase()] || name; + requestHeaders[name] = value; + } + return this; + }, + overrideMimeType: function (type) { + if (completed == null) { + s.mimeType = type; + } + return this; + }, + statusCode: function (map) { + var code; + if (map) { + if (completed) { + jqXHR.always(map[jqXHR.status]); + } else { + for (code in map) { + statusCode[code] = [ + statusCode[code], + map[code] + ]; + } + } + } + return this; + }, + abort: function (statusText) { + var finalText = statusText || strAbort; + if (transport) { + transport.abort(finalText); + } + done(0, finalText); + return this; + } + }; + deferred.promise(jqXHR); + s.url = ((url || s.url || location.href) + '').replace(rprotocol, location.protocol + '//'); + s.type = options.method || options.type || s.method || s.type; + s.dataTypes = (s.dataType || '*').toLowerCase().match(rnothtmlwhite) || ['']; + if (s.crossDomain == null) { + urlAnchor = document.createElement('a'); + try { + urlAnchor.href = s.url; + urlAnchor.href = urlAnchor.href; + s.crossDomain = originAnchor.protocol + '//' + originAnchor.host !== urlAnchor.protocol + '//' + urlAnchor.host; + } catch (e) { + s.crossDomain = true; + } + } + if (s.data && s.processData && typeof s.data !== 'string') { + s.data = jQuery.param(s.data, s.traditional); + } + inspectPrefiltersOrTransports(prefilters, s, options, jqXHR); + if (completed) { + return jqXHR; + } + fireGlobals = jQuery.event && s.global; + if (fireGlobals && jQuery.active++ === 0) { + jQuery.event.trigger('ajaxStart'); + } + s.type = s.type.toUpperCase(); + s.hasContent = !rnoContent.test(s.type); + cacheURL = s.url.replace(rhash, ''); + if (!s.hasContent) { + uncached = s.url.slice(cacheURL.length); + if (s.data && (s.processData || typeof s.data === 'string')) { + cacheURL += (rquery.test(cacheURL) ? '&' : '?') + s.data; + delete s.data; + } + if (s.cache === false) { + cacheURL = cacheURL.replace(rantiCache, '$1'); + uncached = (rquery.test(cacheURL) ? '&' : '?') + '_=' + nonce++ + uncached; + } + s.url = cacheURL + uncached; + } else if (s.data && s.processData && (s.contentType || '').indexOf('application/x-www-form-urlencoded') === 0) { + s.data = s.data.replace(r20, '+'); + } + if (s.ifModified) { + if (jQuery.lastModified[cacheURL]) { + jqXHR.setRequestHeader('If-Modified-Since', jQuery.lastModified[cacheURL]); + } + if (jQuery.etag[cacheURL]) { + jqXHR.setRequestHeader('If-None-Match', jQuery.etag[cacheURL]); + } + } + if (s.data && s.hasContent && s.contentType !== false || options.contentType) { + jqXHR.setRequestHeader('Content-Type', s.contentType); + } + jqXHR.setRequestHeader('Accept', s.dataTypes[0] && s.accepts[s.dataTypes[0]] ? s.accepts[s.dataTypes[0]] + (s.dataTypes[0] !== '*' ? ', ' + allTypes + '; q=0.01' : '') : s.accepts['*']); + for (i in s.headers) { + jqXHR.setRequestHeader(i, s.headers[i]); + } + if (s.beforeSend && (s.beforeSend.call(callbackContext, jqXHR, s) === false || completed)) { + return jqXHR.abort(); + } + strAbort = 'abort'; + completeDeferred.add(s.complete); + jqXHR.done(s.success); + jqXHR.fail(s.error); + transport = inspectPrefiltersOrTransports(transports, s, options, jqXHR); + if (!transport) { + done(-1, 'No Transport'); + } else { + jqXHR.readyState = 1; + if (fireGlobals) { + globalEventContext.trigger('ajaxSend', [ + jqXHR, + s + ]); + } + if (completed) { + return jqXHR; + } + if (s.async && s.timeout > 0) { + timeoutTimer = window.setTimeout(function () { + jqXHR.abort('timeout'); + }, s.timeout); + } + try { + completed = false; + transport.send(requestHeaders, done); + } catch (e) { + if (completed) { + throw e; + } + done(-1, e); + } + } + function done(status, nativeStatusText, responses, headers) { + var isSuccess, success, error, response, modified, statusText = nativeStatusText; + if (completed) { + return; + } + completed = true; + if (timeoutTimer) { + window.clearTimeout(timeoutTimer); + } + transport = undefined; + responseHeadersString = headers || ''; + jqXHR.readyState = status > 0 ? 4 : 0; + isSuccess = status >= 200 && status < 300 || status === 304; + if (responses) { + response = ajaxHandleResponses(s, jqXHR, responses); + } + response = ajaxConvert(s, response, jqXHR, isSuccess); + if (isSuccess) { + if (s.ifModified) { + modified = jqXHR.getResponseHeader('Last-Modified'); + if (modified) { + jQuery.lastModified[cacheURL] = modified; + } + modified = jqXHR.getResponseHeader('etag'); + if (modified) { + jQuery.etag[cacheURL] = modified; + } + } + if (status === 204 || s.type === 'HEAD') { + statusText = 'nocontent'; + } else if (status === 304) { + statusText = 'notmodified'; + } else { + statusText = response.state; + success = response.data; + error = response.error; + isSuccess = !error; + } + } else { + error = statusText; + if (status || !statusText) { + statusText = 'error'; + if (status < 0) { + status = 0; + } + } + } + jqXHR.status = status; + jqXHR.statusText = (nativeStatusText || statusText) + ''; + if (isSuccess) { + deferred.resolveWith(callbackContext, [ + success, + statusText, + jqXHR + ]); + } else { + deferred.rejectWith(callbackContext, [ + jqXHR, + statusText, + error + ]); + } + jqXHR.statusCode(statusCode); + statusCode = undefined; + if (fireGlobals) { + globalEventContext.trigger(isSuccess ? 'ajaxSuccess' : 'ajaxError', [ + jqXHR, + s, + isSuccess ? success : error + ]); + } + completeDeferred.fireWith(callbackContext, [ + jqXHR, + statusText + ]); + if (fireGlobals) { + globalEventContext.trigger('ajaxComplete', [ + jqXHR, + s + ]); + if (!--jQuery.active) { + jQuery.event.trigger('ajaxStop'); + } + } + } + return jqXHR; + }, + getJSON: function (url, data, callback) { + return jQuery.get(url, data, callback, 'json'); + }, + getScript: function (url, callback) { + return jQuery.get(url, undefined, callback, 'script'); + } + }); + jQuery.each([ + 'get', + 'post' + ], function (i, method) { + jQuery[method] = function (url, data, callback, type) { + if (isFunction(data)) { + type = type || callback; + callback = data; + data = undefined; + } + return jQuery.ajax(jQuery.extend({ + url: url, + type: method, + dataType: type, + data: data, + success: callback + }, jQuery.isPlainObject(url) && url)); + }; + }); + jQuery._evalUrl = function (url) { + return jQuery.ajax({ + url: url, + type: 'GET', + dataType: 'script', + cache: true, + async: false, + global: false, + 'throws': true + }); + }; + jQuery.fn.extend({ + wrapAll: function (html) { + var wrap; + if (this[0]) { + if (isFunction(html)) { + html = html.call(this[0]); + } + wrap = jQuery(html, this[0].ownerDocument).eq(0).clone(true); + if (this[0].parentNode) { + wrap.insertBefore(this[0]); + } + wrap.map(function () { + var elem = this; + while (elem.firstElementChild) { + elem = elem.firstElementChild; + } + return elem; + }).append(this); + } + return this; + }, + wrapInner: function (html) { + if (isFunction(html)) { + return this.each(function (i) { + jQuery(this).wrapInner(html.call(this, i)); + }); + } + return this.each(function () { + var self = jQuery(this), contents = self.contents(); + if (contents.length) { + contents.wrapAll(html); + } else { + self.append(html); + } + }); + }, + wrap: function (html) { + var htmlIsFunction = isFunction(html); + return this.each(function (i) { + jQuery(this).wrapAll(htmlIsFunction ? html.call(this, i) : html); + }); + }, + unwrap: function (selector) { + this.parent(selector).not('body').each(function () { + jQuery(this).replaceWith(this.childNodes); + }); + return this; + } + }); + jQuery.expr.pseudos.hidden = function (elem) { + return !jQuery.expr.pseudos.visible(elem); + }; + jQuery.expr.pseudos.visible = function (elem) { + return !!(elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length); + }; + jQuery.ajaxSettings.xhr = function () { + try { + return new window.XMLHttpRequest(); + } catch (e) { + } + }; + var xhrSuccessStatus = { + 0: 200, + 1223: 204 + }, xhrSupported = jQuery.ajaxSettings.xhr(); + support.cors = !!xhrSupported && 'withCredentials' in xhrSupported; + support.ajax = xhrSupported = !!xhrSupported; + jQuery.ajaxTransport(function (options) { + var callback, errorCallback; + if (support.cors || xhrSupported && !options.crossDomain) { + return { + send: function (headers, complete) { + var i, xhr = options.xhr(); + xhr.open(options.type, options.url, options.async, options.username, options.password); + if (options.xhrFields) { + for (i in options.xhrFields) { + xhr[i] = options.xhrFields[i]; + } + } + if (options.mimeType && xhr.overrideMimeType) { + xhr.overrideMimeType(options.mimeType); + } + if (!options.crossDomain && !headers['X-Requested-With']) { + headers['X-Requested-With'] = 'XMLHttpRequest'; + } + for (i in headers) { + xhr.setRequestHeader(i, headers[i]); + } + callback = function (type) { + return function () { + if (callback) { + callback = errorCallback = xhr.onload = xhr.onerror = xhr.onabort = xhr.ontimeout = xhr.onreadystatechange = null; + if (type === 'abort') { + xhr.abort(); + } else if (type === 'error') { + if (typeof xhr.status !== 'number') { + complete(0, 'error'); + } else { + complete(xhr.status, xhr.statusText); + } + } else { + complete(xhrSuccessStatus[xhr.status] || xhr.status, xhr.statusText, (xhr.responseType || 'text') !== 'text' || typeof xhr.responseText !== 'string' ? { binary: xhr.response } : { text: xhr.responseText }, xhr.getAllResponseHeaders()); + } + } + }; + }; + xhr.onload = callback(); + errorCallback = xhr.onerror = xhr.ontimeout = callback('error'); + if (xhr.onabort !== undefined) { + xhr.onabort = errorCallback; + } else { + xhr.onreadystatechange = function () { + if (xhr.readyState === 4) { + window.setTimeout(function () { + if (callback) { + errorCallback(); + } + }); + } + }; + } + callback = callback('abort'); + try { + xhr.send(options.hasContent && options.data || null); + } catch (e) { + if (callback) { + throw e; + } + } + }, + abort: function () { + if (callback) { + callback(); + } + } + }; + } + }); + jQuery.ajaxPrefilter(function (s) { + if (s.crossDomain) { + s.contents.script = false; + } + }); + jQuery.ajaxSetup({ + accepts: { script: 'text/javascript, application/javascript, ' + 'application/ecmascript, application/x-ecmascript' }, + contents: { script: /\b(?:java|ecma)script\b/ }, + converters: { + 'text script': function (text) { + jQuery.globalEval(text); + return text; + } + } + }); + jQuery.ajaxPrefilter('script', function (s) { + if (s.cache === undefined) { + s.cache = false; + } + if (s.crossDomain) { + s.type = 'GET'; + } + }); + jQuery.ajaxTransport('script', function (s) { + if (s.crossDomain) { + var script, callback; + return { + send: function (_, complete) { + script = jQuery('', 'script tag content serialized'); + }); +}); +/*simple-html-tokenizer@0.2.6#lib/simple-html-tokenizer/utils*/ +define('simple-html-tokenizer@0.2.6#lib/simple-html-tokenizer/utils', ['exports'], function (exports) { + 'use strict'; + Object.defineProperty(exports, '__esModule', { value: true }); + var WSP = /[\t\n\f ]/; + var ALPHA = /[A-Za-z]/; + var CRLF = /\r\n?/g; + function isSpace(char) { + return WSP.test(char); + } + function isAlpha(char) { + return ALPHA.test(char); + } + function preprocessInput(input) { + return input.replace(CRLF, '\n'); + } + exports.isSpace = isSpace; + exports.isAlpha = isAlpha; + exports.preprocessInput = preprocessInput; +}); +/*simple-html-tokenizer@0.2.6#lib/simple-html-tokenizer/evented-tokenizer*/ +define('simple-html-tokenizer@0.2.6#lib/simple-html-tokenizer/evented-tokenizer', [ + 'exports', + 'simple-html-tokenizer@0.2.6#lib/simple-html-tokenizer/utils' +], function (exports, _utils) { + 'use strict'; + Object.defineProperty(exports, '__esModule', { value: true }); + function EventedTokenizer(delegate, entityParser) { + this.delegate = delegate; + this.entityParser = entityParser; + this.state = null; + this.input = null; + this.index = -1; + this.line = -1; + this.column = -1; + this.tagLine = -1; + this.tagColumn = -1; + this.reset(); + } + EventedTokenizer.prototype = { + reset: function reset() { + this.state = 'beforeData'; + this.input = ''; + this.index = 0; + this.line = 1; + this.column = 0; + this.tagLine = -1; + this.tagColumn = -1; + this.delegate.reset(); + }, + tokenize: function tokenize(input) { + this.reset(); + this.tokenizePart(input); + this.tokenizeEOF(); + }, + tokenizePart: function tokenizePart(input) { + this.input += (0, _utils.preprocessInput)(input); + while (this.index < this.input.length) { + this.states[this.state].call(this); + } + }, + tokenizeEOF: function tokenizeEOF() { + this.flushData(); + }, + flushData: function flushData() { + if (this.state === 'data') { + this.delegate.finishData(); + this.state = 'beforeData'; + } + }, + peek: function peek() { + return this.input.charAt(this.index); + }, + consume: function consume() { + var char = this.peek(); + this.index++; + if (char === '\n') { + this.line++; + this.column = 0; + } else { + this.column++; + } + return char; + }, + consumeCharRef: function consumeCharRef() { + var endIndex = this.input.indexOf(';', this.index); + if (endIndex === -1) { + return; + } + var entity = this.input.slice(this.index, endIndex); + var chars = this.entityParser.parse(entity); + if (chars) { + var count = entity.length; + while (count) { + this.consume(); + count--; + } + this.consume(); + return chars; + } + }, + markTagStart: function markTagStart() { + this.tagLine = this.line; + this.tagColumn = this.column; + if (this.delegate.tagOpen) { + this.delegate.tagOpen(); + } + }, + states: { + beforeData: function beforeData() { + var char = this.peek(); + if (char === '<') { + this.state = 'tagOpen'; + this.markTagStart(); + this.consume(); + } else { + this.state = 'data'; + this.delegate.beginData(); + } + }, + data: function data() { + var char = this.peek(); + if (char === '<') { + this.delegate.finishData(); + this.state = 'tagOpen'; + this.markTagStart(); + this.consume(); + } else if (char === '&') { + this.consume(); + this.delegate.appendToData(this.consumeCharRef() || '&'); + } else { + this.consume(); + this.delegate.appendToData(char); + } + }, + tagOpen: function tagOpen() { + var char = this.consume(); + if (char === '!') { + this.state = 'markupDeclaration'; + } else if (char === '/') { + this.state = 'endTagOpen'; + } else if ((0, _utils.isAlpha)(char)) { + this.state = 'tagName'; + this.delegate.beginStartTag(); + this.delegate.appendToTagName(char.toLowerCase()); + } + }, + markupDeclaration: function markupDeclaration() { + var char = this.consume(); + if (char === '-' && this.input.charAt(this.index) === '-') { + this.consume(); + this.state = 'commentStart'; + this.delegate.beginComment(); + } + }, + commentStart: function commentStart() { + var char = this.consume(); + if (char === '-') { + this.state = 'commentStartDash'; + } else if (char === '>') { + this.delegate.finishComment(); + this.state = 'beforeData'; + } else { + this.delegate.appendToCommentData(char); + this.state = 'comment'; + } + }, + commentStartDash: function commentStartDash() { + var char = this.consume(); + if (char === '-') { + this.state = 'commentEnd'; + } else if (char === '>') { + this.delegate.finishComment(); + this.state = 'beforeData'; + } else { + this.delegate.appendToCommentData('-'); + this.state = 'comment'; + } + }, + comment: function comment() { + var char = this.consume(); + if (char === '-') { + this.state = 'commentEndDash'; + } else { + this.delegate.appendToCommentData(char); + } + }, + commentEndDash: function commentEndDash() { + var char = this.consume(); + if (char === '-') { + this.state = 'commentEnd'; + } else { + this.delegate.appendToCommentData('-' + char); + this.state = 'comment'; + } + }, + commentEnd: function commentEnd() { + var char = this.consume(); + if (char === '>') { + this.delegate.finishComment(); + this.state = 'beforeData'; + } else { + this.delegate.appendToCommentData('--' + char); + this.state = 'comment'; + } + }, + tagName: function tagName() { + var char = this.consume(); + if ((0, _utils.isSpace)(char)) { + this.state = 'beforeAttributeName'; + } else if (char === '/') { + this.state = 'selfClosingStartTag'; + } else if (char === '>') { + this.delegate.finishTag(); + this.state = 'beforeData'; + } else { + this.delegate.appendToTagName(char); + } + }, + beforeAttributeName: function beforeAttributeName() { + var char = this.peek(); + if ((0, _utils.isSpace)(char)) { + this.consume(); + return; + } else if (char === '/') { + this.state = 'selfClosingStartTag'; + this.consume(); + } else if (char === '>') { + this.consume(); + this.delegate.finishTag(); + this.state = 'beforeData'; + } else { + this.state = 'attributeName'; + this.delegate.beginAttribute(); + this.consume(); + this.delegate.appendToAttributeName(char); + } + }, + attributeName: function attributeName() { + var char = this.peek(); + if ((0, _utils.isSpace)(char)) { + this.state = 'afterAttributeName'; + this.consume(); + } else if (char === '/') { + this.delegate.beginAttributeValue(false); + this.delegate.finishAttributeValue(); + this.consume(); + this.state = 'selfClosingStartTag'; + } else if (char === '=') { + this.state = 'beforeAttributeValue'; + this.consume(); + } else if (char === '>') { + this.delegate.beginAttributeValue(false); + this.delegate.finishAttributeValue(); + this.consume(); + this.delegate.finishTag(); + this.state = 'beforeData'; + } else { + this.consume(); + this.delegate.appendToAttributeName(char); + } + }, + afterAttributeName: function afterAttributeName() { + var char = this.peek(); + if ((0, _utils.isSpace)(char)) { + this.consume(); + return; + } else if (char === '/') { + this.delegate.beginAttributeValue(false); + this.delegate.finishAttributeValue(); + this.consume(); + this.state = 'selfClosingStartTag'; + } else if (char === '=') { + this.consume(); + this.state = 'beforeAttributeValue'; + } else if (char === '>') { + this.delegate.beginAttributeValue(false); + this.delegate.finishAttributeValue(); + this.consume(); + this.delegate.finishTag(); + this.state = 'beforeData'; + } else { + this.delegate.beginAttributeValue(false); + this.delegate.finishAttributeValue(); + this.consume(); + this.state = 'attributeName'; + this.delegate.beginAttribute(); + this.delegate.appendToAttributeName(char); + } + }, + beforeAttributeValue: function beforeAttributeValue() { + var char = this.peek(); + if ((0, _utils.isSpace)(char)) { + this.consume(); + } else if (char === '"') { + this.state = 'attributeValueDoubleQuoted'; + this.delegate.beginAttributeValue(true); + this.consume(); + } else if (char === '\'') { + this.state = 'attributeValueSingleQuoted'; + this.delegate.beginAttributeValue(true); + this.consume(); + } else if (char === '>') { + this.delegate.beginAttributeValue(false); + this.delegate.finishAttributeValue(); + this.consume(); + this.delegate.finishTag(); + this.state = 'beforeData'; + } else { + this.state = 'attributeValueUnquoted'; + this.delegate.beginAttributeValue(false); + this.consume(); + this.delegate.appendToAttributeValue(char); + } + }, + attributeValueDoubleQuoted: function attributeValueDoubleQuoted() { + var char = this.consume(); + if (char === '"') { + this.delegate.finishAttributeValue(); + this.state = 'afterAttributeValueQuoted'; + } else if (char === '&') { + this.delegate.appendToAttributeValue(this.consumeCharRef('"') || '&'); + } else { + this.delegate.appendToAttributeValue(char); + } + }, + attributeValueSingleQuoted: function attributeValueSingleQuoted() { + var char = this.consume(); + if (char === '\'') { + this.delegate.finishAttributeValue(); + this.state = 'afterAttributeValueQuoted'; + } else if (char === '&') { + this.delegate.appendToAttributeValue(this.consumeCharRef('\'') || '&'); + } else { + this.delegate.appendToAttributeValue(char); + } + }, + attributeValueUnquoted: function attributeValueUnquoted() { + var char = this.peek(); + if ((0, _utils.isSpace)(char)) { + this.delegate.finishAttributeValue(); + this.consume(); + this.state = 'beforeAttributeName'; + } else if (char === '&') { + this.consume(); + this.delegate.appendToAttributeValue(this.consumeCharRef('>') || '&'); + } else if (char === '>') { + this.delegate.finishAttributeValue(); + this.consume(); + this.delegate.finishTag(); + this.state = 'beforeData'; + } else { + this.consume(); + this.delegate.appendToAttributeValue(char); + } + }, + afterAttributeValueQuoted: function afterAttributeValueQuoted() { + var char = this.peek(); + if ((0, _utils.isSpace)(char)) { + this.consume(); + this.state = 'beforeAttributeName'; + } else if (char === '/') { + this.consume(); + this.state = 'selfClosingStartTag'; + } else if (char === '>') { + this.consume(); + this.delegate.finishTag(); + this.state = 'beforeData'; + } else { + this.state = 'beforeAttributeName'; + } + }, + selfClosingStartTag: function selfClosingStartTag() { + var char = this.peek(); + if (char === '>') { + this.consume(); + this.delegate.markTagAsSelfClosing(); + this.delegate.finishTag(); + this.state = 'beforeData'; + } else { + this.state = 'beforeAttributeName'; + } + }, + endTagOpen: function endTagOpen() { + var char = this.consume(); + if ((0, _utils.isAlpha)(char)) { + this.state = 'tagName'; + this.delegate.beginEndTag(); + this.delegate.appendToTagName(char.toLowerCase()); + } + } + } + }; + exports.default = EventedTokenizer; +}); +/*simple-html-tokenizer@0.2.6#lib/simple-html-tokenizer/tokenizer*/ +define('simple-html-tokenizer@0.2.6#lib/simple-html-tokenizer/tokenizer', [ + 'exports', + 'simple-html-tokenizer@0.2.6#lib/simple-html-tokenizer/evented-tokenizer' +], function (exports, _eventedTokenizer) { + 'use strict'; + Object.defineProperty(exports, '__esModule', { value: true }); + var _eventedTokenizer2 = _interopRequireDefault(_eventedTokenizer); + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj }; + } + function Tokenizer(entityParser, options) { + this.token = null; + this.startLine = 1; + this.startColumn = 0; + this.options = options || {}; + this.tokenizer = new _eventedTokenizer2.default(this, entityParser); + } + Tokenizer.prototype = { + tokenize: function tokenize(input) { + this.tokens = []; + this.tokenizer.tokenize(input); + return this.tokens; + }, + tokenizePart: function tokenizePart(input) { + this.tokens = []; + this.tokenizer.tokenizePart(input); + return this.tokens; + }, + tokenizeEOF: function tokenizeEOF() { + this.tokens = []; + this.tokenizer.tokenizeEOF(); + return this.tokens[0]; + }, + reset: function reset() { + this.token = null; + this.startLine = 1; + this.startColumn = 0; + }, + addLocInfo: function addLocInfo() { + if (this.options.loc) { + this.token.loc = { + start: { + line: this.startLine, + column: this.startColumn + }, + end: { + line: this.tokenizer.line, + column: this.tokenizer.column + } + }; + } + this.startLine = this.tokenizer.line; + this.startColumn = this.tokenizer.column; + }, + beginData: function beginData() { + this.token = { + type: 'Chars', + chars: '' + }; + this.tokens.push(this.token); + }, + appendToData: function appendToData(char) { + this.token.chars += char; + }, + finishData: function finishData() { + this.addLocInfo(); + }, + beginComment: function beginComment() { + this.token = { + type: 'Comment', + chars: '' + }; + this.tokens.push(this.token); + }, + appendToCommentData: function appendToCommentData(char) { + this.token.chars += char; + }, + finishComment: function finishComment() { + this.addLocInfo(); + }, + beginStartTag: function beginStartTag() { + this.token = { + type: 'StartTag', + tagName: '', + attributes: [], + selfClosing: false + }; + this.tokens.push(this.token); + }, + beginEndTag: function beginEndTag() { + this.token = { + type: 'EndTag', + tagName: '' + }; + this.tokens.push(this.token); + }, + finishTag: function finishTag() { + this.addLocInfo(); + }, + markTagAsSelfClosing: function markTagAsSelfClosing() { + this.token.selfClosing = true; + }, + appendToTagName: function appendToTagName(char) { + this.token.tagName += char; + }, + beginAttribute: function beginAttribute() { + this._currentAttribute = [ + '', + '', + null + ]; + this.token.attributes.push(this._currentAttribute); + }, + appendToAttributeName: function appendToAttributeName(char) { + this._currentAttribute[0] += char; + }, + beginAttributeValue: function beginAttributeValue(isQuoted) { + this._currentAttribute[2] = isQuoted; + }, + appendToAttributeValue: function appendToAttributeValue(char) { + this._currentAttribute[1] = this._currentAttribute[1] || ''; + this._currentAttribute[1] += char; + }, + finishAttributeValue: function finishAttributeValue() { + } + }; + exports.default = Tokenizer; +}); +/*simple-html-tokenizer@0.2.6#lib/simple-html-tokenizer/entity-parser*/ +define('simple-html-tokenizer@0.2.6#lib/simple-html-tokenizer/entity-parser', ['exports'], function (exports) { + 'use strict'; + Object.defineProperty(exports, '__esModule', { value: true }); + function EntityParser(named) { + this.named = named; + } + var HEXCHARCODE = /^#[xX]([A-Fa-f0-9]+)$/; + var CHARCODE = /^#([0-9]+)$/; + var NAMED = /^([A-Za-z0-9]+)$/; + EntityParser.prototype.parse = function (entity) { + if (!entity) { + return; + } + var matches = entity.match(HEXCHARCODE); + if (matches) { + return String.fromCharCode(parseInt(matches[1], 16)); + } + matches = entity.match(CHARCODE); + if (matches) { + return String.fromCharCode(parseInt(matches[1], 10)); + } + matches = entity.match(NAMED); + if (matches) { + return this.named[matches[1]]; + } + }; + exports.default = EntityParser; +}); +/*simple-html-tokenizer@0.2.6#lib/simple-html-tokenizer/html5-named-char-refs*/ +define('simple-html-tokenizer@0.2.6#lib/simple-html-tokenizer/html5-named-char-refs', ['exports'], function (exports) { + 'use strict'; + Object.defineProperty(exports, '__esModule', { value: true }); + var namedCharRefs = { + Aacute: 'Á', + aacute: 'á', + Abreve: 'Ă', + abreve: 'ă', + ac: '\u223E', + acd: '\u223F', + acE: '\u223E̳', + Acirc: 'Â', + acirc: 'â', + acute: '\xB4', + Acy: 'А', + acy: 'а', + AElig: 'Æ', + aelig: 'æ', + af: '\u2061', + Afr: '\uD835\uDD04', + afr: '\uD835\uDD1E', + Agrave: 'À', + agrave: 'à', + alefsym: 'ℵ', + aleph: 'ℵ', + Alpha: 'Α', + alpha: 'α', + Amacr: 'Ā', + amacr: 'ā', + amalg: '\u2A3F', + AMP: '&', + amp: '&', + And: '\u2A53', + and: '\u2227', + andand: '\u2A55', + andd: '\u2A5C', + andslope: '\u2A58', + andv: '\u2A5A', + ang: '\u2220', + ange: '\u29A4', + angle: '\u2220', + angmsd: '\u2221', + angmsdaa: '\u29A8', + angmsdab: '\u29A9', + angmsdac: '\u29AA', + angmsdad: '\u29AB', + angmsdae: '\u29AC', + angmsdaf: '\u29AD', + angmsdag: '\u29AE', + angmsdah: '\u29AF', + angrt: '\u221F', + angrtvb: '\u22BE', + angrtvbd: '\u299D', + angsph: '\u2222', + angst: 'Å', + angzarr: '\u237C', + Aogon: 'Ą', + aogon: 'ą', + Aopf: '\uD835\uDD38', + aopf: '\uD835\uDD52', + ap: '\u2248', + apacir: '\u2A6F', + apE: '\u2A70', + ape: '\u224A', + apid: '\u224B', + apos: '\'', + ApplyFunction: '\u2061', + approx: '\u2248', + approxeq: '\u224A', + Aring: 'Å', + aring: 'å', + Ascr: '\uD835\uDC9C', + ascr: '\uD835\uDCB6', + Assign: '\u2254', + ast: '*', + asymp: '\u2248', + asympeq: '\u224D', + Atilde: 'Ã', + atilde: 'ã', + Auml: 'Ä', + auml: 'ä', + awconint: '\u2233', + awint: '\u2A11', + backcong: '\u224C', + backepsilon: '\u03F6', + backprime: '\u2035', + backsim: '\u223D', + backsimeq: '\u22CD', + Backslash: '\u2216', + Barv: '\u2AE7', + barvee: '\u22BD', + Barwed: '\u2306', + barwed: '\u2305', + barwedge: '\u2305', + bbrk: '\u23B5', + bbrktbrk: '\u23B6', + bcong: '\u224C', + Bcy: 'Б', + bcy: 'б', + bdquo: '\u201E', + becaus: '\u2235', + Because: '\u2235', + because: '\u2235', + bemptyv: '\u29B0', + bepsi: '\u03F6', + bernou: 'ℬ', + Bernoullis: 'ℬ', + Beta: 'Β', + beta: 'β', + beth: 'ℶ', + between: '\u226C', + Bfr: '\uD835\uDD05', + bfr: '\uD835\uDD1F', + bigcap: '\u22C2', + bigcirc: '\u25EF', + bigcup: '\u22C3', + bigodot: '\u2A00', + bigoplus: '\u2A01', + bigotimes: '\u2A02', + bigsqcup: '\u2A06', + bigstar: '\u2605', + bigtriangledown: '\u25BD', + bigtriangleup: '\u25B3', + biguplus: '\u2A04', + bigvee: '\u22C1', + bigwedge: '\u22C0', + bkarow: '\u290D', + blacklozenge: '\u29EB', + blacksquare: '\u25AA', + blacktriangle: '\u25B4', + blacktriangledown: '\u25BE', + blacktriangleleft: '\u25C2', + blacktriangleright: '\u25B8', + blank: '\u2423', + blk12: '\u2592', + blk14: '\u2591', + blk34: '\u2593', + block: '\u2588', + bne: '=⃥', + bnequiv: '\u2261⃥', + bNot: '\u2AED', + bnot: '\u2310', + Bopf: '\uD835\uDD39', + bopf: '\uD835\uDD53', + bot: '\u22A5', + bottom: '\u22A5', + bowtie: '\u22C8', + boxbox: '\u29C9', + boxDL: '\u2557', + boxDl: '\u2556', + boxdL: '\u2555', + boxdl: '\u2510', + boxDR: '\u2554', + boxDr: '\u2553', + boxdR: '\u2552', + boxdr: '\u250C', + boxH: '\u2550', + boxh: '\u2500', + boxHD: '\u2566', + boxHd: '\u2564', + boxhD: '\u2565', + boxhd: '\u252C', + boxHU: '\u2569', + boxHu: '\u2567', + boxhU: '\u2568', + boxhu: '\u2534', + boxminus: '\u229F', + boxplus: '\u229E', + boxtimes: '\u22A0', + boxUL: '\u255D', + boxUl: '\u255C', + boxuL: '\u255B', + boxul: '\u2518', + boxUR: '\u255A', + boxUr: '\u2559', + boxuR: '\u2558', + boxur: '\u2514', + boxV: '\u2551', + boxv: '\u2502', + boxVH: '\u256C', + boxVh: '\u256B', + boxvH: '\u256A', + boxvh: '\u253C', + boxVL: '\u2563', + boxVl: '\u2562', + boxvL: '\u2561', + boxvl: '\u2524', + boxVR: '\u2560', + boxVr: '\u255F', + boxvR: '\u255E', + boxvr: '\u251C', + bprime: '\u2035', + Breve: '\u02D8', + breve: '\u02D8', + brvbar: '\xA6', + Bscr: 'ℬ', + bscr: '\uD835\uDCB7', + bsemi: '\u204F', + bsim: '\u223D', + bsime: '\u22CD', + bsol: '\\', + bsolb: '\u29C5', + bsolhsub: '\u27C8', + bull: '\u2022', + bullet: '\u2022', + bump: '\u224E', + bumpE: '\u2AAE', + bumpe: '\u224F', + Bumpeq: '\u224E', + bumpeq: '\u224F', + Cacute: 'Ć', + cacute: 'ć', + Cap: '\u22D2', + cap: '\u2229', + capand: '\u2A44', + capbrcup: '\u2A49', + capcap: '\u2A4B', + capcup: '\u2A47', + capdot: '\u2A40', + CapitalDifferentialD: 'ⅅ', + caps: '\u2229︀', + caret: '\u2041', + caron: 'ˇ', + Cayleys: 'ℭ', + ccaps: '\u2A4D', + Ccaron: 'Č', + ccaron: 'č', + Ccedil: 'Ç', + ccedil: 'ç', + Ccirc: 'Ĉ', + ccirc: 'ĉ', + Cconint: '\u2230', + ccups: '\u2A4C', + ccupssm: '\u2A50', + Cdot: 'Ċ', + cdot: 'ċ', + cedil: '\xB8', + Cedilla: '\xB8', + cemptyv: '\u29B2', + cent: '\xA2', + CenterDot: '\xB7', + centerdot: '\xB7', + Cfr: 'ℭ', + cfr: '\uD835\uDD20', + CHcy: 'Ч', + chcy: 'ч', + check: '\u2713', + checkmark: '\u2713', + Chi: 'Χ', + chi: 'χ', + cir: '\u25CB', + circ: 'ˆ', + circeq: '\u2257', + circlearrowleft: '\u21BA', + circlearrowright: '\u21BB', + circledast: '\u229B', + circledcirc: '\u229A', + circleddash: '\u229D', + CircleDot: '\u2299', + circledR: '\xAE', + circledS: '\u24C8', + CircleMinus: '\u2296', + CirclePlus: '\u2295', + CircleTimes: '\u2297', + cirE: '\u29C3', + cire: '\u2257', + cirfnint: '\u2A10', + cirmid: '\u2AEF', + cirscir: '\u29C2', + ClockwiseContourIntegral: '\u2232', + CloseCurlyDoubleQuote: '\u201D', + CloseCurlyQuote: '\u2019', + clubs: '\u2663', + clubsuit: '\u2663', + Colon: '\u2237', + colon: ':', + Colone: '\u2A74', + colone: '\u2254', + coloneq: '\u2254', + comma: ',', + commat: '@', + comp: '\u2201', + compfn: '\u2218', + complement: '\u2201', + complexes: 'ℂ', + cong: '\u2245', + congdot: '\u2A6D', + Congruent: '\u2261', + Conint: '\u222F', + conint: '\u222E', + ContourIntegral: '\u222E', + Copf: 'ℂ', + copf: '\uD835\uDD54', + coprod: '\u2210', + Coproduct: '\u2210', + COPY: '\xA9', + copy: '\xA9', + copysr: '\u2117', + CounterClockwiseContourIntegral: '\u2233', + crarr: '\u21B5', + Cross: '\u2A2F', + cross: '\u2717', + Cscr: '\uD835\uDC9E', + cscr: '\uD835\uDCB8', + csub: '\u2ACF', + csube: '\u2AD1', + csup: '\u2AD0', + csupe: '\u2AD2', + ctdot: '\u22EF', + cudarrl: '\u2938', + cudarrr: '\u2935', + cuepr: '\u22DE', + cuesc: '\u22DF', + cularr: '\u21B6', + cularrp: '\u293D', + Cup: '\u22D3', + cup: '\u222A', + cupbrcap: '\u2A48', + CupCap: '\u224D', + cupcap: '\u2A46', + cupcup: '\u2A4A', + cupdot: '\u228D', + cupor: '\u2A45', + cups: '\u222A︀', + curarr: '\u21B7', + curarrm: '\u293C', + curlyeqprec: '\u22DE', + curlyeqsucc: '\u22DF', + curlyvee: '\u22CE', + curlywedge: '\u22CF', + curren: '\xA4', + curvearrowleft: '\u21B6', + curvearrowright: '\u21B7', + cuvee: '\u22CE', + cuwed: '\u22CF', + cwconint: '\u2232', + cwint: '\u2231', + cylcty: '\u232D', + Dagger: '\u2021', + dagger: '\u2020', + daleth: 'ℸ', + Darr: '\u21A1', + dArr: '\u21D3', + darr: '\u2193', + dash: '\u2010', + Dashv: '\u2AE4', + dashv: '\u22A3', + dbkarow: '\u290F', + dblac: '\u02DD', + Dcaron: 'Ď', + dcaron: 'ď', + Dcy: 'Д', + dcy: 'д', + DD: 'ⅅ', + dd: 'ⅆ', + ddagger: '\u2021', + ddarr: '\u21CA', + DDotrahd: '\u2911', + ddotseq: '\u2A77', + deg: '\xB0', + Del: '\u2207', + Delta: 'Δ', + delta: 'δ', + demptyv: '\u29B1', + dfisht: '\u297F', + Dfr: '\uD835\uDD07', + dfr: '\uD835\uDD21', + dHar: '\u2965', + dharl: '\u21C3', + dharr: '\u21C2', + DiacriticalAcute: '\xB4', + DiacriticalDot: '\u02D9', + DiacriticalDoubleAcute: '\u02DD', + DiacriticalGrave: '`', + DiacriticalTilde: '\u02DC', + diam: '\u22C4', + Diamond: '\u22C4', + diamond: '\u22C4', + diamondsuit: '\u2666', + diams: '\u2666', + die: '\xA8', + DifferentialD: 'ⅆ', + digamma: 'ϝ', + disin: '\u22F2', + div: '\xF7', + divide: '\xF7', + divideontimes: '\u22C7', + divonx: '\u22C7', + DJcy: 'Ђ', + djcy: 'ђ', + dlcorn: '\u231E', + dlcrop: '\u230D', + dollar: '$', + Dopf: '\uD835\uDD3B', + dopf: '\uD835\uDD55', + Dot: '\xA8', + dot: '\u02D9', + DotDot: '⃜', + doteq: '\u2250', + doteqdot: '\u2251', + DotEqual: '\u2250', + dotminus: '\u2238', + dotplus: '\u2214', + dotsquare: '\u22A1', + doublebarwedge: '\u2306', + DoubleContourIntegral: '\u222F', + DoubleDot: '\xA8', + DoubleDownArrow: '\u21D3', + DoubleLeftArrow: '\u21D0', + DoubleLeftRightArrow: '\u21D4', + DoubleLeftTee: '\u2AE4', + DoubleLongLeftArrow: '\u27F8', + DoubleLongLeftRightArrow: '\u27FA', + DoubleLongRightArrow: '\u27F9', + DoubleRightArrow: '\u21D2', + DoubleRightTee: '\u22A8', + DoubleUpArrow: '\u21D1', + DoubleUpDownArrow: '\u21D5', + DoubleVerticalBar: '\u2225', + DownArrow: '\u2193', + Downarrow: '\u21D3', + downarrow: '\u2193', + DownArrowBar: '\u2913', + DownArrowUpArrow: '\u21F5', + DownBreve: '̑', + downdownarrows: '\u21CA', + downharpoonleft: '\u21C3', + downharpoonright: '\u21C2', + DownLeftRightVector: '\u2950', + DownLeftTeeVector: '\u295E', + DownLeftVector: '\u21BD', + DownLeftVectorBar: '\u2956', + DownRightTeeVector: '\u295F', + DownRightVector: '\u21C1', + DownRightVectorBar: '\u2957', + DownTee: '\u22A4', + DownTeeArrow: '\u21A7', + drbkarow: '\u2910', + drcorn: '\u231F', + drcrop: '\u230C', + Dscr: '\uD835\uDC9F', + dscr: '\uD835\uDCB9', + DScy: 'Ѕ', + dscy: 'ѕ', + dsol: '\u29F6', + Dstrok: 'Đ', + dstrok: 'đ', + dtdot: '\u22F1', + dtri: '\u25BF', + dtrif: '\u25BE', + duarr: '\u21F5', + duhar: '\u296F', + dwangle: '\u29A6', + DZcy: 'Џ', + dzcy: 'џ', + dzigrarr: '\u27FF', + Eacute: 'É', + eacute: 'é', + easter: '\u2A6E', + Ecaron: 'Ě', + ecaron: 'ě', + ecir: '\u2256', + Ecirc: 'Ê', + ecirc: 'ê', + ecolon: '\u2255', + Ecy: 'Э', + ecy: 'э', + eDDot: '\u2A77', + Edot: 'Ė', + eDot: '\u2251', + edot: 'ė', + ee: 'ⅇ', + efDot: '\u2252', + Efr: '\uD835\uDD08', + efr: '\uD835\uDD22', + eg: '\u2A9A', + Egrave: 'È', + egrave: 'è', + egs: '\u2A96', + egsdot: '\u2A98', + el: '\u2A99', + Element: '\u2208', + elinters: '\u23E7', + ell: 'ℓ', + els: '\u2A95', + elsdot: '\u2A97', + Emacr: 'Ē', + emacr: 'ē', + empty: '\u2205', + emptyset: '\u2205', + EmptySmallSquare: '\u25FB', + emptyv: '\u2205', + EmptyVerySmallSquare: '\u25AB', + emsp: '\u2003', + emsp13: '\u2004', + emsp14: '\u2005', + ENG: 'Ŋ', + eng: 'ŋ', + ensp: '\u2002', + Eogon: 'Ę', + eogon: 'ę', + Eopf: '\uD835\uDD3C', + eopf: '\uD835\uDD56', + epar: '\u22D5', + eparsl: '\u29E3', + eplus: '\u2A71', + epsi: 'ε', + Epsilon: 'Ε', + epsilon: 'ε', + epsiv: 'ϵ', + eqcirc: '\u2256', + eqcolon: '\u2255', + eqsim: '\u2242', + eqslantgtr: '\u2A96', + eqslantless: '\u2A95', + Equal: '\u2A75', + equals: '=', + EqualTilde: '\u2242', + equest: '\u225F', + Equilibrium: '\u21CC', + equiv: '\u2261', + equivDD: '\u2A78', + eqvparsl: '\u29E5', + erarr: '\u2971', + erDot: '\u2253', + Escr: 'ℰ', + escr: 'ℯ', + esdot: '\u2250', + Esim: '\u2A73', + esim: '\u2242', + Eta: 'Η', + eta: 'η', + ETH: 'Ð', + eth: 'ð', + Euml: 'Ë', + euml: 'ë', + euro: '\u20AC', + excl: '!', + exist: '\u2203', + Exists: '\u2203', + expectation: 'ℰ', + ExponentialE: 'ⅇ', + exponentiale: 'ⅇ', + fallingdotseq: '\u2252', + Fcy: 'Ф', + fcy: 'ф', + female: '\u2640', + ffilig: 'ffi', + fflig: 'ff', + ffllig: 'ffl', + Ffr: '\uD835\uDD09', + ffr: '\uD835\uDD23', + filig: 'fi', + FilledSmallSquare: '\u25FC', + FilledVerySmallSquare: '\u25AA', + fjlig: 'fj', + flat: '\u266D', + fllig: 'fl', + fltns: '\u25B1', + fnof: 'ƒ', + Fopf: '\uD835\uDD3D', + fopf: '\uD835\uDD57', + ForAll: '\u2200', + forall: '\u2200', + fork: '\u22D4', + forkv: '\u2AD9', + Fouriertrf: 'ℱ', + fpartint: '\u2A0D', + frac12: '\xBD', + frac13: '\u2153', + frac14: '\xBC', + frac15: '\u2155', + frac16: '\u2159', + frac18: '\u215B', + frac23: '\u2154', + frac25: '\u2156', + frac34: '\xBE', + frac35: '\u2157', + frac38: '\u215C', + frac45: '\u2158', + frac56: '\u215A', + frac58: '\u215D', + frac78: '\u215E', + frasl: '\u2044', + frown: '\u2322', + Fscr: 'ℱ', + fscr: '\uD835\uDCBB', + gacute: 'ǵ', + Gamma: 'Γ', + gamma: 'γ', + Gammad: 'Ϝ', + gammad: 'ϝ', + gap: '\u2A86', + Gbreve: 'Ğ', + gbreve: 'ğ', + Gcedil: 'Ģ', + Gcirc: 'Ĝ', + gcirc: 'ĝ', + Gcy: 'Г', + gcy: 'г', + Gdot: 'Ġ', + gdot: 'ġ', + gE: '\u2267', + ge: '\u2265', + gEl: '\u2A8C', + gel: '\u22DB', + geq: '\u2265', + geqq: '\u2267', + geqslant: '\u2A7E', + ges: '\u2A7E', + gescc: '\u2AA9', + gesdot: '\u2A80', + gesdoto: '\u2A82', + gesdotol: '\u2A84', + gesl: '\u22DB︀', + gesles: '\u2A94', + Gfr: '\uD835\uDD0A', + gfr: '\uD835\uDD24', + Gg: '\u22D9', + gg: '\u226B', + ggg: '\u22D9', + gimel: 'ℷ', + GJcy: 'Ѓ', + gjcy: 'ѓ', + gl: '\u2277', + gla: '\u2AA5', + glE: '\u2A92', + glj: '\u2AA4', + gnap: '\u2A8A', + gnapprox: '\u2A8A', + gnE: '\u2269', + gne: '\u2A88', + gneq: '\u2A88', + gneqq: '\u2269', + gnsim: '\u22E7', + Gopf: '\uD835\uDD3E', + gopf: '\uD835\uDD58', + grave: '`', + GreaterEqual: '\u2265', + GreaterEqualLess: '\u22DB', + GreaterFullEqual: '\u2267', + GreaterGreater: '\u2AA2', + GreaterLess: '\u2277', + GreaterSlantEqual: '\u2A7E', + GreaterTilde: '\u2273', + Gscr: '\uD835\uDCA2', + gscr: 'ℊ', + gsim: '\u2273', + gsime: '\u2A8E', + gsiml: '\u2A90', + GT: '>', + Gt: '\u226B', + gt: '>', + gtcc: '\u2AA7', + gtcir: '\u2A7A', + gtdot: '\u22D7', + gtlPar: '\u2995', + gtquest: '\u2A7C', + gtrapprox: '\u2A86', + gtrarr: '\u2978', + gtrdot: '\u22D7', + gtreqless: '\u22DB', + gtreqqless: '\u2A8C', + gtrless: '\u2277', + gtrsim: '\u2273', + gvertneqq: '\u2269︀', + gvnE: '\u2269︀', + Hacek: 'ˇ', + hairsp: '\u200A', + half: '\xBD', + hamilt: 'ℋ', + HARDcy: 'Ъ', + hardcy: 'ъ', + hArr: '\u21D4', + harr: '\u2194', + harrcir: '\u2948', + harrw: '\u21AD', + Hat: '^', + hbar: 'ℏ', + Hcirc: 'Ĥ', + hcirc: 'ĥ', + hearts: '\u2665', + heartsuit: '\u2665', + hellip: '\u2026', + hercon: '\u22B9', + Hfr: 'ℌ', + hfr: '\uD835\uDD25', + HilbertSpace: 'ℋ', + hksearow: '\u2925', + hkswarow: '\u2926', + hoarr: '\u21FF', + homtht: '\u223B', + hookleftarrow: '\u21A9', + hookrightarrow: '\u21AA', + Hopf: 'ℍ', + hopf: '\uD835\uDD59', + horbar: '\u2015', + HorizontalLine: '\u2500', + Hscr: 'ℋ', + hscr: '\uD835\uDCBD', + hslash: 'ℏ', + Hstrok: 'Ħ', + hstrok: 'ħ', + HumpDownHump: '\u224E', + HumpEqual: '\u224F', + hybull: '\u2043', + hyphen: '\u2010', + Iacute: 'Í', + iacute: 'í', + ic: '\u2063', + Icirc: 'Î', + icirc: 'î', + Icy: 'И', + icy: 'и', + Idot: 'İ', + IEcy: 'Е', + iecy: 'е', + iexcl: '\xA1', + iff: '\u21D4', + Ifr: 'ℑ', + ifr: '\uD835\uDD26', + Igrave: 'Ì', + igrave: 'ì', + ii: 'ⅈ', + iiiint: '\u2A0C', + iiint: '\u222D', + iinfin: '\u29DC', + iiota: '\u2129', + IJlig: 'IJ', + ijlig: 'ij', + Im: 'ℑ', + Imacr: 'Ī', + imacr: 'ī', + image: 'ℑ', + ImaginaryI: 'ⅈ', + imagline: 'ℐ', + imagpart: 'ℑ', + imath: 'ı', + imof: '\u22B7', + imped: 'Ƶ', + Implies: '\u21D2', + in: '\u2208', + incare: '\u2105', + infin: '\u221E', + infintie: '\u29DD', + inodot: 'ı', + Int: '\u222C', + int: '\u222B', + intcal: '\u22BA', + integers: 'ℤ', + Integral: '\u222B', + intercal: '\u22BA', + Intersection: '\u22C2', + intlarhk: '\u2A17', + intprod: '\u2A3C', + InvisibleComma: '\u2063', + InvisibleTimes: '\u2062', + IOcy: 'Ё', + iocy: 'ё', + Iogon: 'Į', + iogon: 'į', + Iopf: '\uD835\uDD40', + iopf: '\uD835\uDD5A', + Iota: 'Ι', + iota: 'ι', + iprod: '\u2A3C', + iquest: '\xBF', + Iscr: 'ℐ', + iscr: '\uD835\uDCBE', + isin: '\u2208', + isindot: '\u22F5', + isinE: '\u22F9', + isins: '\u22F4', + isinsv: '\u22F3', + isinv: '\u2208', + it: '\u2062', + Itilde: 'Ĩ', + itilde: 'ĩ', + Iukcy: 'І', + iukcy: 'і', + Iuml: 'Ï', + iuml: 'ï', + Jcirc: 'Ĵ', + jcirc: 'ĵ', + Jcy: 'Й', + jcy: 'й', + Jfr: '\uD835\uDD0D', + jfr: '\uD835\uDD27', + jmath: 'ȷ', + Jopf: '\uD835\uDD41', + jopf: '\uD835\uDD5B', + Jscr: '\uD835\uDCA5', + jscr: '\uD835\uDCBF', + Jsercy: 'Ј', + jsercy: 'ј', + Jukcy: 'Є', + jukcy: 'є', + Kappa: 'Κ', + kappa: 'κ', + kappav: 'ϰ', + Kcedil: 'Ķ', + kcedil: 'ķ', + Kcy: 'К', + kcy: 'к', + Kfr: '\uD835\uDD0E', + kfr: '\uD835\uDD28', + kgreen: 'ĸ', + KHcy: 'Х', + khcy: 'х', + KJcy: 'Ќ', + kjcy: 'ќ', + Kopf: '\uD835\uDD42', + kopf: '\uD835\uDD5C', + Kscr: '\uD835\uDCA6', + kscr: '\uD835\uDCC0', + lAarr: '\u21DA', + Lacute: 'Ĺ', + lacute: 'ĺ', + laemptyv: '\u29B4', + lagran: 'ℒ', + Lambda: 'Λ', + lambda: 'λ', + Lang: '\u27EA', + lang: '\u27E8', + langd: '\u2991', + langle: '\u27E8', + lap: '\u2A85', + Laplacetrf: 'ℒ', + laquo: '\xAB', + Larr: '\u219E', + lArr: '\u21D0', + larr: '\u2190', + larrb: '\u21E4', + larrbfs: '\u291F', + larrfs: '\u291D', + larrhk: '\u21A9', + larrlp: '\u21AB', + larrpl: '\u2939', + larrsim: '\u2973', + larrtl: '\u21A2', + lat: '\u2AAB', + lAtail: '\u291B', + latail: '\u2919', + late: '\u2AAD', + lates: '\u2AAD︀', + lBarr: '\u290E', + lbarr: '\u290C', + lbbrk: '\u2772', + lbrace: '{', + lbrack: '[', + lbrke: '\u298B', + lbrksld: '\u298F', + lbrkslu: '\u298D', + Lcaron: 'Ľ', + lcaron: 'ľ', + Lcedil: 'Ļ', + lcedil: 'ļ', + lceil: '\u2308', + lcub: '{', + Lcy: 'Л', + lcy: 'л', + ldca: '\u2936', + ldquo: '\u201C', + ldquor: '\u201E', + ldrdhar: '\u2967', + ldrushar: '\u294B', + ldsh: '\u21B2', + lE: '\u2266', + le: '\u2264', + LeftAngleBracket: '\u27E8', + LeftArrow: '\u2190', + Leftarrow: '\u21D0', + leftarrow: '\u2190', + LeftArrowBar: '\u21E4', + LeftArrowRightArrow: '\u21C6', + leftarrowtail: '\u21A2', + LeftCeiling: '\u2308', + LeftDoubleBracket: '\u27E6', + LeftDownTeeVector: '\u2961', + LeftDownVector: '\u21C3', + LeftDownVectorBar: '\u2959', + LeftFloor: '\u230A', + leftharpoondown: '\u21BD', + leftharpoonup: '\u21BC', + leftleftarrows: '\u21C7', + LeftRightArrow: '\u2194', + Leftrightarrow: '\u21D4', + leftrightarrow: '\u2194', + leftrightarrows: '\u21C6', + leftrightharpoons: '\u21CB', + leftrightsquigarrow: '\u21AD', + LeftRightVector: '\u294E', + LeftTee: '\u22A3', + LeftTeeArrow: '\u21A4', + LeftTeeVector: '\u295A', + leftthreetimes: '\u22CB', + LeftTriangle: '\u22B2', + LeftTriangleBar: '\u29CF', + LeftTriangleEqual: '\u22B4', + LeftUpDownVector: '\u2951', + LeftUpTeeVector: '\u2960', + LeftUpVector: '\u21BF', + LeftUpVectorBar: '\u2958', + LeftVector: '\u21BC', + LeftVectorBar: '\u2952', + lEg: '\u2A8B', + leg: '\u22DA', + leq: '\u2264', + leqq: '\u2266', + leqslant: '\u2A7D', + les: '\u2A7D', + lescc: '\u2AA8', + lesdot: '\u2A7F', + lesdoto: '\u2A81', + lesdotor: '\u2A83', + lesg: '\u22DA︀', + lesges: '\u2A93', + lessapprox: '\u2A85', + lessdot: '\u22D6', + lesseqgtr: '\u22DA', + lesseqqgtr: '\u2A8B', + LessEqualGreater: '\u22DA', + LessFullEqual: '\u2266', + LessGreater: '\u2276', + lessgtr: '\u2276', + LessLess: '\u2AA1', + lesssim: '\u2272', + LessSlantEqual: '\u2A7D', + LessTilde: '\u2272', + lfisht: '\u297C', + lfloor: '\u230A', + Lfr: '\uD835\uDD0F', + lfr: '\uD835\uDD29', + lg: '\u2276', + lgE: '\u2A91', + lHar: '\u2962', + lhard: '\u21BD', + lharu: '\u21BC', + lharul: '\u296A', + lhblk: '\u2584', + LJcy: 'Љ', + ljcy: 'љ', + Ll: '\u22D8', + ll: '\u226A', + llarr: '\u21C7', + llcorner: '\u231E', + Lleftarrow: '\u21DA', + llhard: '\u296B', + lltri: '\u25FA', + Lmidot: 'Ŀ', + lmidot: 'ŀ', + lmoust: '\u23B0', + lmoustache: '\u23B0', + lnap: '\u2A89', + lnapprox: '\u2A89', + lnE: '\u2268', + lne: '\u2A87', + lneq: '\u2A87', + lneqq: '\u2268', + lnsim: '\u22E6', + loang: '\u27EC', + loarr: '\u21FD', + lobrk: '\u27E6', + LongLeftArrow: '\u27F5', + Longleftarrow: '\u27F8', + longleftarrow: '\u27F5', + LongLeftRightArrow: '\u27F7', + Longleftrightarrow: '\u27FA', + longleftrightarrow: '\u27F7', + longmapsto: '\u27FC', + LongRightArrow: '\u27F6', + Longrightarrow: '\u27F9', + longrightarrow: '\u27F6', + looparrowleft: '\u21AB', + looparrowright: '\u21AC', + lopar: '\u2985', + Lopf: '\uD835\uDD43', + lopf: '\uD835\uDD5D', + loplus: '\u2A2D', + lotimes: '\u2A34', + lowast: '\u2217', + lowbar: '_', + LowerLeftArrow: '\u2199', + LowerRightArrow: '\u2198', + loz: '\u25CA', + lozenge: '\u25CA', + lozf: '\u29EB', + lpar: '(', + lparlt: '\u2993', + lrarr: '\u21C6', + lrcorner: '\u231F', + lrhar: '\u21CB', + lrhard: '\u296D', + lrm: '\u200E', + lrtri: '\u22BF', + lsaquo: '\u2039', + Lscr: 'ℒ', + lscr: '\uD835\uDCC1', + Lsh: '\u21B0', + lsh: '\u21B0', + lsim: '\u2272', + lsime: '\u2A8D', + lsimg: '\u2A8F', + lsqb: '[', + lsquo: '\u2018', + lsquor: '\u201A', + Lstrok: 'Ł', + lstrok: 'ł', + LT: '<', + Lt: '\u226A', + lt: '<', + ltcc: '\u2AA6', + ltcir: '\u2A79', + ltdot: '\u22D6', + lthree: '\u22CB', + ltimes: '\u22C9', + ltlarr: '\u2976', + ltquest: '\u2A7B', + ltri: '\u25C3', + ltrie: '\u22B4', + ltrif: '\u25C2', + ltrPar: '\u2996', + lurdshar: '\u294A', + luruhar: '\u2966', + lvertneqq: '\u2268︀', + lvnE: '\u2268︀', + macr: '\xAF', + male: '\u2642', + malt: '\u2720', + maltese: '\u2720', + Map: '\u2905', + map: '\u21A6', + mapsto: '\u21A6', + mapstodown: '\u21A7', + mapstoleft: '\u21A4', + mapstoup: '\u21A5', + marker: '\u25AE', + mcomma: '\u2A29', + Mcy: 'М', + mcy: 'м', + mdash: '\u2014', + mDDot: '\u223A', + measuredangle: '\u2221', + MediumSpace: '\u205F', + Mellintrf: 'ℳ', + Mfr: '\uD835\uDD10', + mfr: '\uD835\uDD2A', + mho: '\u2127', + micro: 'µ', + mid: '\u2223', + midast: '*', + midcir: '\u2AF0', + middot: '\xB7', + minus: '\u2212', + minusb: '\u229F', + minusd: '\u2238', + minusdu: '\u2A2A', + MinusPlus: '\u2213', + mlcp: '\u2ADB', + mldr: '\u2026', + mnplus: '\u2213', + models: '\u22A7', + Mopf: '\uD835\uDD44', + mopf: '\uD835\uDD5E', + mp: '\u2213', + Mscr: 'ℳ', + mscr: '\uD835\uDCC2', + mstpos: '\u223E', + Mu: 'Μ', + mu: 'μ', + multimap: '\u22B8', + mumap: '\u22B8', + nabla: '\u2207', + Nacute: 'Ń', + nacute: 'ń', + nang: '\u2220⃒', + nap: '\u2249', + napE: '\u2A70̸', + napid: '\u224B̸', + napos: 'ʼn', + napprox: '\u2249', + natur: '\u266E', + natural: '\u266E', + naturals: 'ℕ', + nbsp: '\xA0', + nbump: '\u224E̸', + nbumpe: '\u224F̸', + ncap: '\u2A43', + Ncaron: 'Ň', + ncaron: 'ň', + Ncedil: 'Ņ', + ncedil: 'ņ', + ncong: '\u2247', + ncongdot: '\u2A6D̸', + ncup: '\u2A42', + Ncy: 'Н', + ncy: 'н', + ndash: '\u2013', + ne: '\u2260', + nearhk: '\u2924', + neArr: '\u21D7', + nearr: '\u2197', + nearrow: '\u2197', + nedot: '\u2250̸', + NegativeMediumSpace: '\u200B', + NegativeThickSpace: '\u200B', + NegativeThinSpace: '\u200B', + NegativeVeryThinSpace: '\u200B', + nequiv: '\u2262', + nesear: '\u2928', + nesim: '\u2242̸', + NestedGreaterGreater: '\u226B', + NestedLessLess: '\u226A', + NewLine: '\n', + nexist: '\u2204', + nexists: '\u2204', + Nfr: '\uD835\uDD11', + nfr: '\uD835\uDD2B', + ngE: '\u2267̸', + nge: '\u2271', + ngeq: '\u2271', + ngeqq: '\u2267̸', + ngeqslant: '\u2A7E̸', + nges: '\u2A7E̸', + nGg: '\u22D9̸', + ngsim: '\u2275', + nGt: '\u226B⃒', + ngt: '\u226F', + ngtr: '\u226F', + nGtv: '\u226B̸', + nhArr: '\u21CE', + nharr: '\u21AE', + nhpar: '\u2AF2', + ni: '\u220B', + nis: '\u22FC', + nisd: '\u22FA', + niv: '\u220B', + NJcy: 'Њ', + njcy: 'њ', + nlArr: '\u21CD', + nlarr: '\u219A', + nldr: '\u2025', + nlE: '\u2266̸', + nle: '\u2270', + nLeftarrow: '\u21CD', + nleftarrow: '\u219A', + nLeftrightarrow: '\u21CE', + nleftrightarrow: '\u21AE', + nleq: '\u2270', + nleqq: '\u2266̸', + nleqslant: '\u2A7D̸', + nles: '\u2A7D̸', + nless: '\u226E', + nLl: '\u22D8̸', + nlsim: '\u2274', + nLt: '\u226A⃒', + nlt: '\u226E', + nltri: '\u22EA', + nltrie: '\u22EC', + nLtv: '\u226A̸', + nmid: '\u2224', + NoBreak: '\u2060', + NonBreakingSpace: '\xA0', + Nopf: 'ℕ', + nopf: '\uD835\uDD5F', + Not: '\u2AEC', + not: '\xAC', + NotCongruent: '\u2262', + NotCupCap: '\u226D', + NotDoubleVerticalBar: '\u2226', + NotElement: '\u2209', + NotEqual: '\u2260', + NotEqualTilde: '\u2242̸', + NotExists: '\u2204', + NotGreater: '\u226F', + NotGreaterEqual: '\u2271', + NotGreaterFullEqual: '\u2267̸', + NotGreaterGreater: '\u226B̸', + NotGreaterLess: '\u2279', + NotGreaterSlantEqual: '\u2A7E̸', + NotGreaterTilde: '\u2275', + NotHumpDownHump: '\u224E̸', + NotHumpEqual: '\u224F̸', + notin: '\u2209', + notindot: '\u22F5̸', + notinE: '\u22F9̸', + notinva: '\u2209', + notinvb: '\u22F7', + notinvc: '\u22F6', + NotLeftTriangle: '\u22EA', + NotLeftTriangleBar: '\u29CF̸', + NotLeftTriangleEqual: '\u22EC', + NotLess: '\u226E', + NotLessEqual: '\u2270', + NotLessGreater: '\u2278', + NotLessLess: '\u226A̸', + NotLessSlantEqual: '\u2A7D̸', + NotLessTilde: '\u2274', + NotNestedGreaterGreater: '\u2AA2̸', + NotNestedLessLess: '\u2AA1̸', + notni: '\u220C', + notniva: '\u220C', + notnivb: '\u22FE', + notnivc: '\u22FD', + NotPrecedes: '\u2280', + NotPrecedesEqual: '\u2AAF̸', + NotPrecedesSlantEqual: '\u22E0', + NotReverseElement: '\u220C', + NotRightTriangle: '\u22EB', + NotRightTriangleBar: '\u29D0̸', + NotRightTriangleEqual: '\u22ED', + NotSquareSubset: '\u228F̸', + NotSquareSubsetEqual: '\u22E2', + NotSquareSuperset: '\u2290̸', + NotSquareSupersetEqual: '\u22E3', + NotSubset: '\u2282⃒', + NotSubsetEqual: '\u2288', + NotSucceeds: '\u2281', + NotSucceedsEqual: '\u2AB0̸', + NotSucceedsSlantEqual: '\u22E1', + NotSucceedsTilde: '\u227F̸', + NotSuperset: '\u2283⃒', + NotSupersetEqual: '\u2289', + NotTilde: '\u2241', + NotTildeEqual: '\u2244', + NotTildeFullEqual: '\u2247', + NotTildeTilde: '\u2249', + NotVerticalBar: '\u2224', + npar: '\u2226', + nparallel: '\u2226', + nparsl: '\u2AFD⃥', + npart: '\u2202̸', + npolint: '\u2A14', + npr: '\u2280', + nprcue: '\u22E0', + npre: '\u2AAF̸', + nprec: '\u2280', + npreceq: '\u2AAF̸', + nrArr: '\u21CF', + nrarr: '\u219B', + nrarrc: '\u2933̸', + nrarrw: '\u219D̸', + nRightarrow: '\u21CF', + nrightarrow: '\u219B', + nrtri: '\u22EB', + nrtrie: '\u22ED', + nsc: '\u2281', + nsccue: '\u22E1', + nsce: '\u2AB0̸', + Nscr: '\uD835\uDCA9', + nscr: '\uD835\uDCC3', + nshortmid: '\u2224', + nshortparallel: '\u2226', + nsim: '\u2241', + nsime: '\u2244', + nsimeq: '\u2244', + nsmid: '\u2224', + nspar: '\u2226', + nsqsube: '\u22E2', + nsqsupe: '\u22E3', + nsub: '\u2284', + nsubE: '\u2AC5̸', + nsube: '\u2288', + nsubset: '\u2282⃒', + nsubseteq: '\u2288', + nsubseteqq: '\u2AC5̸', + nsucc: '\u2281', + nsucceq: '\u2AB0̸', + nsup: '\u2285', + nsupE: '\u2AC6̸', + nsupe: '\u2289', + nsupset: '\u2283⃒', + nsupseteq: '\u2289', + nsupseteqq: '\u2AC6̸', + ntgl: '\u2279', + Ntilde: 'Ñ', + ntilde: 'ñ', + ntlg: '\u2278', + ntriangleleft: '\u22EA', + ntrianglelefteq: '\u22EC', + ntriangleright: '\u22EB', + ntrianglerighteq: '\u22ED', + Nu: 'Ν', + nu: 'ν', + num: '#', + numero: '\u2116', + numsp: '\u2007', + nvap: '\u224D⃒', + nVDash: '\u22AF', + nVdash: '\u22AE', + nvDash: '\u22AD', + nvdash: '\u22AC', + nvge: '\u2265⃒', + nvgt: '>⃒', + nvHarr: '\u2904', + nvinfin: '\u29DE', + nvlArr: '\u2902', + nvle: '\u2264⃒', + nvlt: '<⃒', + nvltrie: '\u22B4⃒', + nvrArr: '\u2903', + nvrtrie: '\u22B5⃒', + nvsim: '\u223C⃒', + nwarhk: '\u2923', + nwArr: '\u21D6', + nwarr: '\u2196', + nwarrow: '\u2196', + nwnear: '\u2927', + Oacute: 'Ó', + oacute: 'ó', + oast: '\u229B', + ocir: '\u229A', + Ocirc: 'Ô', + ocirc: 'ô', + Ocy: 'О', + ocy: 'о', + odash: '\u229D', + Odblac: 'Ő', + odblac: 'ő', + odiv: '\u2A38', + odot: '\u2299', + odsold: '\u29BC', + OElig: 'Œ', + oelig: 'œ', + ofcir: '\u29BF', + Ofr: '\uD835\uDD12', + ofr: '\uD835\uDD2C', + ogon: '\u02DB', + Ograve: 'Ò', + ograve: 'ò', + ogt: '\u29C1', + ohbar: '\u29B5', + ohm: 'Ω', + oint: '\u222E', + olarr: '\u21BA', + olcir: '\u29BE', + olcross: '\u29BB', + oline: '\u203E', + olt: '\u29C0', + Omacr: 'Ō', + omacr: 'ō', + Omega: 'Ω', + omega: 'ω', + Omicron: 'Ο', + omicron: 'ο', + omid: '\u29B6', + ominus: '\u2296', + Oopf: '\uD835\uDD46', + oopf: '\uD835\uDD60', + opar: '\u29B7', + OpenCurlyDoubleQuote: '\u201C', + OpenCurlyQuote: '\u2018', + operp: '\u29B9', + oplus: '\u2295', + Or: '\u2A54', + or: '\u2228', + orarr: '\u21BB', + ord: '\u2A5D', + order: 'ℴ', + orderof: 'ℴ', + ordf: 'ª', + ordm: 'º', + origof: '\u22B6', + oror: '\u2A56', + orslope: '\u2A57', + orv: '\u2A5B', + oS: '\u24C8', + Oscr: '\uD835\uDCAA', + oscr: 'ℴ', + Oslash: 'Ø', + oslash: 'ø', + osol: '\u2298', + Otilde: 'Õ', + otilde: 'õ', + Otimes: '\u2A37', + otimes: '\u2297', + otimesas: '\u2A36', + Ouml: 'Ö', + ouml: 'ö', + ovbar: '\u233D', + OverBar: '\u203E', + OverBrace: '\u23DE', + OverBracket: '\u23B4', + OverParenthesis: '\u23DC', + par: '\u2225', + para: '\xB6', + parallel: '\u2225', + parsim: '\u2AF3', + parsl: '\u2AFD', + part: '\u2202', + PartialD: '\u2202', + Pcy: 'П', + pcy: 'п', + percnt: '%', + period: '.', + permil: '\u2030', + perp: '\u22A5', + pertenk: '\u2031', + Pfr: '\uD835\uDD13', + pfr: '\uD835\uDD2D', + Phi: 'Φ', + phi: 'φ', + phiv: 'ϕ', + phmmat: 'ℳ', + phone: '\u260E', + Pi: 'Π', + pi: 'π', + pitchfork: '\u22D4', + piv: 'ϖ', + planck: 'ℏ', + planckh: 'ℎ', + plankv: 'ℏ', + plus: '+', + plusacir: '\u2A23', + plusb: '\u229E', + pluscir: '\u2A22', + plusdo: '\u2214', + plusdu: '\u2A25', + pluse: '\u2A72', + PlusMinus: '\xB1', + plusmn: '\xB1', + plussim: '\u2A26', + plustwo: '\u2A27', + pm: '\xB1', + Poincareplane: 'ℌ', + pointint: '\u2A15', + Popf: 'ℙ', + popf: '\uD835\uDD61', + pound: '\xA3', + Pr: '\u2ABB', + pr: '\u227A', + prap: '\u2AB7', + prcue: '\u227C', + prE: '\u2AB3', + pre: '\u2AAF', + prec: '\u227A', + precapprox: '\u2AB7', + preccurlyeq: '\u227C', + Precedes: '\u227A', + PrecedesEqual: '\u2AAF', + PrecedesSlantEqual: '\u227C', + PrecedesTilde: '\u227E', + preceq: '\u2AAF', + precnapprox: '\u2AB9', + precneqq: '\u2AB5', + precnsim: '\u22E8', + precsim: '\u227E', + Prime: '\u2033', + prime: '\u2032', + primes: 'ℙ', + prnap: '\u2AB9', + prnE: '\u2AB5', + prnsim: '\u22E8', + prod: '\u220F', + Product: '\u220F', + profalar: '\u232E', + profline: '\u2312', + profsurf: '\u2313', + prop: '\u221D', + Proportion: '\u2237', + Proportional: '\u221D', + propto: '\u221D', + prsim: '\u227E', + prurel: '\u22B0', + Pscr: '\uD835\uDCAB', + pscr: '\uD835\uDCC5', + Psi: 'Ψ', + psi: 'ψ', + puncsp: '\u2008', + Qfr: '\uD835\uDD14', + qfr: '\uD835\uDD2E', + qint: '\u2A0C', + Qopf: 'ℚ', + qopf: '\uD835\uDD62', + qprime: '\u2057', + Qscr: '\uD835\uDCAC', + qscr: '\uD835\uDCC6', + quaternions: 'ℍ', + quatint: '\u2A16', + quest: '?', + questeq: '\u225F', + QUOT: '"', + quot: '"', + rAarr: '\u21DB', + race: '\u223Ḏ', + Racute: 'Ŕ', + racute: 'ŕ', + radic: '\u221A', + raemptyv: '\u29B3', + Rang: '\u27EB', + rang: '\u27E9', + rangd: '\u2992', + range: '\u29A5', + rangle: '\u27E9', + raquo: '\xBB', + Rarr: '\u21A0', + rArr: '\u21D2', + rarr: '\u2192', + rarrap: '\u2975', + rarrb: '\u21E5', + rarrbfs: '\u2920', + rarrc: '\u2933', + rarrfs: '\u291E', + rarrhk: '\u21AA', + rarrlp: '\u21AC', + rarrpl: '\u2945', + rarrsim: '\u2974', + Rarrtl: '\u2916', + rarrtl: '\u21A3', + rarrw: '\u219D', + rAtail: '\u291C', + ratail: '\u291A', + ratio: '\u2236', + rationals: 'ℚ', + RBarr: '\u2910', + rBarr: '\u290F', + rbarr: '\u290D', + rbbrk: '\u2773', + rbrace: '}', + rbrack: ']', + rbrke: '\u298C', + rbrksld: '\u298E', + rbrkslu: '\u2990', + Rcaron: 'Ř', + rcaron: 'ř', + Rcedil: 'Ŗ', + rcedil: 'ŗ', + rceil: '\u2309', + rcub: '}', + Rcy: 'Р', + rcy: 'р', + rdca: '\u2937', + rdldhar: '\u2969', + rdquo: '\u201D', + rdquor: '\u201D', + rdsh: '\u21B3', + Re: 'ℜ', + real: 'ℜ', + realine: 'ℛ', + realpart: 'ℜ', + reals: 'ℝ', + rect: '\u25AD', + REG: '\xAE', + reg: '\xAE', + ReverseElement: '\u220B', + ReverseEquilibrium: '\u21CB', + ReverseUpEquilibrium: '\u296F', + rfisht: '\u297D', + rfloor: '\u230B', + Rfr: 'ℜ', + rfr: '\uD835\uDD2F', + rHar: '\u2964', + rhard: '\u21C1', + rharu: '\u21C0', + rharul: '\u296C', + Rho: 'Ρ', + rho: 'ρ', + rhov: 'ϱ', + RightAngleBracket: '\u27E9', + RightArrow: '\u2192', + Rightarrow: '\u21D2', + rightarrow: '\u2192', + RightArrowBar: '\u21E5', + RightArrowLeftArrow: '\u21C4', + rightarrowtail: '\u21A3', + RightCeiling: '\u2309', + RightDoubleBracket: '\u27E7', + RightDownTeeVector: '\u295D', + RightDownVector: '\u21C2', + RightDownVectorBar: '\u2955', + RightFloor: '\u230B', + rightharpoondown: '\u21C1', + rightharpoonup: '\u21C0', + rightleftarrows: '\u21C4', + rightleftharpoons: '\u21CC', + rightrightarrows: '\u21C9', + rightsquigarrow: '\u219D', + RightTee: '\u22A2', + RightTeeArrow: '\u21A6', + RightTeeVector: '\u295B', + rightthreetimes: '\u22CC', + RightTriangle: '\u22B3', + RightTriangleBar: '\u29D0', + RightTriangleEqual: '\u22B5', + RightUpDownVector: '\u294F', + RightUpTeeVector: '\u295C', + RightUpVector: '\u21BE', + RightUpVectorBar: '\u2954', + RightVector: '\u21C0', + RightVectorBar: '\u2953', + ring: '\u02DA', + risingdotseq: '\u2253', + rlarr: '\u21C4', + rlhar: '\u21CC', + rlm: '\u200F', + rmoust: '\u23B1', + rmoustache: '\u23B1', + rnmid: '\u2AEE', + roang: '\u27ED', + roarr: '\u21FE', + robrk: '\u27E7', + ropar: '\u2986', + Ropf: 'ℝ', + ropf: '\uD835\uDD63', + roplus: '\u2A2E', + rotimes: '\u2A35', + RoundImplies: '\u2970', + rpar: ')', + rpargt: '\u2994', + rppolint: '\u2A12', + rrarr: '\u21C9', + Rrightarrow: '\u21DB', + rsaquo: '\u203A', + Rscr: 'ℛ', + rscr: '\uD835\uDCC7', + Rsh: '\u21B1', + rsh: '\u21B1', + rsqb: ']', + rsquo: '\u2019', + rsquor: '\u2019', + rthree: '\u22CC', + rtimes: '\u22CA', + rtri: '\u25B9', + rtrie: '\u22B5', + rtrif: '\u25B8', + rtriltri: '\u29CE', + RuleDelayed: '\u29F4', + ruluhar: '\u2968', + rx: '\u211E', + Sacute: 'Ś', + sacute: 'ś', + sbquo: '\u201A', + Sc: '\u2ABC', + sc: '\u227B', + scap: '\u2AB8', + Scaron: 'Š', + scaron: 'š', + sccue: '\u227D', + scE: '\u2AB4', + sce: '\u2AB0', + Scedil: 'Ş', + scedil: 'ş', + Scirc: 'Ŝ', + scirc: 'ŝ', + scnap: '\u2ABA', + scnE: '\u2AB6', + scnsim: '\u22E9', + scpolint: '\u2A13', + scsim: '\u227F', + Scy: 'С', + scy: 'с', + sdot: '\u22C5', + sdotb: '\u22A1', + sdote: '\u2A66', + searhk: '\u2925', + seArr: '\u21D8', + searr: '\u2198', + searrow: '\u2198', + sect: '\xA7', + semi: ';', + seswar: '\u2929', + setminus: '\u2216', + setmn: '\u2216', + sext: '\u2736', + Sfr: '\uD835\uDD16', + sfr: '\uD835\uDD30', + sfrown: '\u2322', + sharp: '\u266F', + SHCHcy: 'Щ', + shchcy: 'щ', + SHcy: 'Ш', + shcy: 'ш', + ShortDownArrow: '\u2193', + ShortLeftArrow: '\u2190', + shortmid: '\u2223', + shortparallel: '\u2225', + ShortRightArrow: '\u2192', + ShortUpArrow: '\u2191', + shy: '\xAD', + Sigma: 'Σ', + sigma: 'σ', + sigmaf: 'ς', + sigmav: 'ς', + sim: '\u223C', + simdot: '\u2A6A', + sime: '\u2243', + simeq: '\u2243', + simg: '\u2A9E', + simgE: '\u2AA0', + siml: '\u2A9D', + simlE: '\u2A9F', + simne: '\u2246', + simplus: '\u2A24', + simrarr: '\u2972', + slarr: '\u2190', + SmallCircle: '\u2218', + smallsetminus: '\u2216', + smashp: '\u2A33', + smeparsl: '\u29E4', + smid: '\u2223', + smile: '\u2323', + smt: '\u2AAA', + smte: '\u2AAC', + smtes: '\u2AAC︀', + SOFTcy: 'Ь', + softcy: 'ь', + sol: '/', + solb: '\u29C4', + solbar: '\u233F', + Sopf: '\uD835\uDD4A', + sopf: '\uD835\uDD64', + spades: '\u2660', + spadesuit: '\u2660', + spar: '\u2225', + sqcap: '\u2293', + sqcaps: '\u2293︀', + sqcup: '\u2294', + sqcups: '\u2294︀', + Sqrt: '\u221A', + sqsub: '\u228F', + sqsube: '\u2291', + sqsubset: '\u228F', + sqsubseteq: '\u2291', + sqsup: '\u2290', + sqsupe: '\u2292', + sqsupset: '\u2290', + sqsupseteq: '\u2292', + squ: '\u25A1', + Square: '\u25A1', + square: '\u25A1', + SquareIntersection: '\u2293', + SquareSubset: '\u228F', + SquareSubsetEqual: '\u2291', + SquareSuperset: '\u2290', + SquareSupersetEqual: '\u2292', + SquareUnion: '\u2294', + squarf: '\u25AA', + squf: '\u25AA', + srarr: '\u2192', + Sscr: '\uD835\uDCAE', + sscr: '\uD835\uDCC8', + ssetmn: '\u2216', + ssmile: '\u2323', + sstarf: '\u22C6', + Star: '\u22C6', + star: '\u2606', + starf: '\u2605', + straightepsilon: 'ϵ', + straightphi: 'ϕ', + strns: '\xAF', + Sub: '\u22D0', + sub: '\u2282', + subdot: '\u2ABD', + subE: '\u2AC5', + sube: '\u2286', + subedot: '\u2AC3', + submult: '\u2AC1', + subnE: '\u2ACB', + subne: '\u228A', + subplus: '\u2ABF', + subrarr: '\u2979', + Subset: '\u22D0', + subset: '\u2282', + subseteq: '\u2286', + subseteqq: '\u2AC5', + SubsetEqual: '\u2286', + subsetneq: '\u228A', + subsetneqq: '\u2ACB', + subsim: '\u2AC7', + subsub: '\u2AD5', + subsup: '\u2AD3', + succ: '\u227B', + succapprox: '\u2AB8', + succcurlyeq: '\u227D', + Succeeds: '\u227B', + SucceedsEqual: '\u2AB0', + SucceedsSlantEqual: '\u227D', + SucceedsTilde: '\u227F', + succeq: '\u2AB0', + succnapprox: '\u2ABA', + succneqq: '\u2AB6', + succnsim: '\u22E9', + succsim: '\u227F', + SuchThat: '\u220B', + Sum: '\u2211', + sum: '\u2211', + sung: '\u266A', + Sup: '\u22D1', + sup: '\u2283', + sup1: '\xB9', + sup2: '\xB2', + sup3: '\xB3', + supdot: '\u2ABE', + supdsub: '\u2AD8', + supE: '\u2AC6', + supe: '\u2287', + supedot: '\u2AC4', + Superset: '\u2283', + SupersetEqual: '\u2287', + suphsol: '\u27C9', + suphsub: '\u2AD7', + suplarr: '\u297B', + supmult: '\u2AC2', + supnE: '\u2ACC', + supne: '\u228B', + supplus: '\u2AC0', + Supset: '\u22D1', + supset: '\u2283', + supseteq: '\u2287', + supseteqq: '\u2AC6', + supsetneq: '\u228B', + supsetneqq: '\u2ACC', + supsim: '\u2AC8', + supsub: '\u2AD4', + supsup: '\u2AD6', + swarhk: '\u2926', + swArr: '\u21D9', + swarr: '\u2199', + swarrow: '\u2199', + swnwar: '\u292A', + szlig: 'ß', + Tab: '\t', + target: '\u2316', + Tau: 'Τ', + tau: 'τ', + tbrk: '\u23B4', + Tcaron: 'Ť', + tcaron: 'ť', + Tcedil: 'Ţ', + tcedil: 'ţ', + Tcy: 'Т', + tcy: 'т', + tdot: '⃛', + telrec: '\u2315', + Tfr: '\uD835\uDD17', + tfr: '\uD835\uDD31', + there4: '\u2234', + Therefore: '\u2234', + therefore: '\u2234', + Theta: 'Θ', + theta: 'θ', + thetasym: 'ϑ', + thetav: 'ϑ', + thickapprox: '\u2248', + thicksim: '\u223C', + ThickSpace: '\u205F\u200A', + thinsp: '\u2009', + ThinSpace: '\u2009', + thkap: '\u2248', + thksim: '\u223C', + THORN: 'Þ', + thorn: 'þ', + Tilde: '\u223C', + tilde: '\u02DC', + TildeEqual: '\u2243', + TildeFullEqual: '\u2245', + TildeTilde: '\u2248', + times: '\xD7', + timesb: '\u22A0', + timesbar: '\u2A31', + timesd: '\u2A30', + tint: '\u222D', + toea: '\u2928', + top: '\u22A4', + topbot: '\u2336', + topcir: '\u2AF1', + Topf: '\uD835\uDD4B', + topf: '\uD835\uDD65', + topfork: '\u2ADA', + tosa: '\u2929', + tprime: '\u2034', + TRADE: '\u2122', + trade: '\u2122', + triangle: '\u25B5', + triangledown: '\u25BF', + triangleleft: '\u25C3', + trianglelefteq: '\u22B4', + triangleq: '\u225C', + triangleright: '\u25B9', + trianglerighteq: '\u22B5', + tridot: '\u25EC', + trie: '\u225C', + triminus: '\u2A3A', + TripleDot: '⃛', + triplus: '\u2A39', + trisb: '\u29CD', + tritime: '\u2A3B', + trpezium: '\u23E2', + Tscr: '\uD835\uDCAF', + tscr: '\uD835\uDCC9', + TScy: 'Ц', + tscy: 'ц', + TSHcy: 'Ћ', + tshcy: 'ћ', + Tstrok: 'Ŧ', + tstrok: 'ŧ', + twixt: '\u226C', + twoheadleftarrow: '\u219E', + twoheadrightarrow: '\u21A0', + Uacute: 'Ú', + uacute: 'ú', + Uarr: '\u219F', + uArr: '\u21D1', + uarr: '\u2191', + Uarrocir: '\u2949', + Ubrcy: 'Ў', + ubrcy: 'ў', + Ubreve: 'Ŭ', + ubreve: 'ŭ', + Ucirc: 'Û', + ucirc: 'û', + Ucy: 'У', + ucy: 'у', + udarr: '\u21C5', + Udblac: 'Ű', + udblac: 'ű', + udhar: '\u296E', + ufisht: '\u297E', + Ufr: '\uD835\uDD18', + ufr: '\uD835\uDD32', + Ugrave: 'Ù', + ugrave: 'ù', + uHar: '\u2963', + uharl: '\u21BF', + uharr: '\u21BE', + uhblk: '\u2580', + ulcorn: '\u231C', + ulcorner: '\u231C', + ulcrop: '\u230F', + ultri: '\u25F8', + Umacr: 'Ū', + umacr: 'ū', + uml: '\xA8', + UnderBar: '_', + UnderBrace: '\u23DF', + UnderBracket: '\u23B5', + UnderParenthesis: '\u23DD', + Union: '\u22C3', + UnionPlus: '\u228E', + Uogon: 'Ų', + uogon: 'ų', + Uopf: '\uD835\uDD4C', + uopf: '\uD835\uDD66', + UpArrow: '\u2191', + Uparrow: '\u21D1', + uparrow: '\u2191', + UpArrowBar: '\u2912', + UpArrowDownArrow: '\u21C5', + UpDownArrow: '\u2195', + Updownarrow: '\u21D5', + updownarrow: '\u2195', + UpEquilibrium: '\u296E', + upharpoonleft: '\u21BF', + upharpoonright: '\u21BE', + uplus: '\u228E', + UpperLeftArrow: '\u2196', + UpperRightArrow: '\u2197', + Upsi: 'ϒ', + upsi: 'υ', + upsih: 'ϒ', + Upsilon: 'Υ', + upsilon: 'υ', + UpTee: '\u22A5', + UpTeeArrow: '\u21A5', + upuparrows: '\u21C8', + urcorn: '\u231D', + urcorner: '\u231D', + urcrop: '\u230E', + Uring: 'Ů', + uring: 'ů', + urtri: '\u25F9', + Uscr: '\uD835\uDCB0', + uscr: '\uD835\uDCCA', + utdot: '\u22F0', + Utilde: 'Ũ', + utilde: 'ũ', + utri: '\u25B5', + utrif: '\u25B4', + uuarr: '\u21C8', + Uuml: 'Ü', + uuml: 'ü', + uwangle: '\u29A7', + vangrt: '\u299C', + varepsilon: 'ϵ', + varkappa: 'ϰ', + varnothing: '\u2205', + varphi: 'ϕ', + varpi: 'ϖ', + varpropto: '\u221D', + vArr: '\u21D5', + varr: '\u2195', + varrho: 'ϱ', + varsigma: 'ς', + varsubsetneq: '\u228A︀', + varsubsetneqq: '\u2ACB︀', + varsupsetneq: '\u228B︀', + varsupsetneqq: '\u2ACC︀', + vartheta: 'ϑ', + vartriangleleft: '\u22B2', + vartriangleright: '\u22B3', + Vbar: '\u2AEB', + vBar: '\u2AE8', + vBarv: '\u2AE9', + Vcy: 'В', + vcy: 'в', + VDash: '\u22AB', + Vdash: '\u22A9', + vDash: '\u22A8', + vdash: '\u22A2', + Vdashl: '\u2AE6', + Vee: '\u22C1', + vee: '\u2228', + veebar: '\u22BB', + veeeq: '\u225A', + vellip: '\u22EE', + Verbar: '\u2016', + verbar: '|', + Vert: '\u2016', + vert: '|', + VerticalBar: '\u2223', + VerticalLine: '|', + VerticalSeparator: '\u2758', + VerticalTilde: '\u2240', + VeryThinSpace: '\u200A', + Vfr: '\uD835\uDD19', + vfr: '\uD835\uDD33', + vltri: '\u22B2', + vnsub: '\u2282⃒', + vnsup: '\u2283⃒', + Vopf: '\uD835\uDD4D', + vopf: '\uD835\uDD67', + vprop: '\u221D', + vrtri: '\u22B3', + Vscr: '\uD835\uDCB1', + vscr: '\uD835\uDCCB', + vsubnE: '\u2ACB︀', + vsubne: '\u228A︀', + vsupnE: '\u2ACC︀', + vsupne: '\u228B︀', + Vvdash: '\u22AA', + vzigzag: '\u299A', + Wcirc: 'Ŵ', + wcirc: 'ŵ', + wedbar: '\u2A5F', + Wedge: '\u22C0', + wedge: '\u2227', + wedgeq: '\u2259', + weierp: '\u2118', + Wfr: '\uD835\uDD1A', + wfr: '\uD835\uDD34', + Wopf: '\uD835\uDD4E', + wopf: '\uD835\uDD68', + wp: '\u2118', + wr: '\u2240', + wreath: '\u2240', + Wscr: '\uD835\uDCB2', + wscr: '\uD835\uDCCC', + xcap: '\u22C2', + xcirc: '\u25EF', + xcup: '\u22C3', + xdtri: '\u25BD', + Xfr: '\uD835\uDD1B', + xfr: '\uD835\uDD35', + xhArr: '\u27FA', + xharr: '\u27F7', + Xi: 'Ξ', + xi: 'ξ', + xlArr: '\u27F8', + xlarr: '\u27F5', + xmap: '\u27FC', + xnis: '\u22FB', + xodot: '\u2A00', + Xopf: '\uD835\uDD4F', + xopf: '\uD835\uDD69', + xoplus: '\u2A01', + xotime: '\u2A02', + xrArr: '\u27F9', + xrarr: '\u27F6', + Xscr: '\uD835\uDCB3', + xscr: '\uD835\uDCCD', + xsqcup: '\u2A06', + xuplus: '\u2A04', + xutri: '\u25B3', + xvee: '\u22C1', + xwedge: '\u22C0', + Yacute: 'Ý', + yacute: 'ý', + YAcy: 'Я', + yacy: 'я', + Ycirc: 'Ŷ', + ycirc: 'ŷ', + Ycy: 'Ы', + ycy: 'ы', + yen: '\xA5', + Yfr: '\uD835\uDD1C', + yfr: '\uD835\uDD36', + YIcy: 'Ї', + yicy: 'ї', + Yopf: '\uD835\uDD50', + yopf: '\uD835\uDD6A', + Yscr: '\uD835\uDCB4', + yscr: '\uD835\uDCCE', + YUcy: 'Ю', + yucy: 'ю', + Yuml: 'Ÿ', + yuml: 'ÿ', + Zacute: 'Ź', + zacute: 'ź', + Zcaron: 'Ž', + zcaron: 'ž', + Zcy: 'З', + zcy: 'з', + Zdot: 'Ż', + zdot: 'ż', + zeetrf: 'ℨ', + ZeroWidthSpace: '\u200B', + Zeta: 'Ζ', + zeta: 'ζ', + Zfr: 'ℨ', + zfr: '\uD835\uDD37', + ZHcy: 'Ж', + zhcy: 'ж', + zigrarr: '\u21DD', + Zopf: 'ℤ', + zopf: '\uD835\uDD6B', + Zscr: '\uD835\uDCB5', + zscr: '\uD835\uDCCF', + zwj: '‍', + zwnj: '‌' + }; + exports.default = namedCharRefs; +}); +/*simple-html-tokenizer@0.2.6#lib/simple-html-tokenizer/tokenize*/ +define('simple-html-tokenizer@0.2.6#lib/simple-html-tokenizer/tokenize', [ + 'exports', + 'simple-html-tokenizer@0.2.6#lib/simple-html-tokenizer/tokenizer', + 'simple-html-tokenizer@0.2.6#lib/simple-html-tokenizer/entity-parser', + 'simple-html-tokenizer@0.2.6#lib/simple-html-tokenizer/html5-named-char-refs' +], function (exports, _tokenizer, _entityParser, _html5NamedCharRefs) { + 'use strict'; + Object.defineProperty(exports, '__esModule', { value: true }); + var _tokenizer2 = _interopRequireDefault(_tokenizer); + var _entityParser2 = _interopRequireDefault(_entityParser); + var _html5NamedCharRefs2 = _interopRequireDefault(_html5NamedCharRefs); + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj }; + } + function tokenize(input, options) { + var tokenizer = new _tokenizer2.default(new _entityParser2.default(_html5NamedCharRefs2.default), options); + return tokenizer.tokenize(input); + } + exports.default = tokenize; +}); +/*can-simple-dom@1.4.2#lib/default-tokenize*/ +define('can-simple-dom@1.4.2#lib/default-tokenize', [ + 'require', + 'exports', + 'module', + 'simple-html-tokenizer/lib/simple-html-tokenizer/tokenize' +], function (require, exports, module) { + var tokenize = require('simple-html-tokenizer/lib/simple-html-tokenizer/tokenize').default; + module.exports = function (input) { + return tokenize(input); + }; +}); +/*can-simple-dom@1.4.2#test/element-sp-test*/ +define('can-simple-dom@1.4.2#test/element-sp-test', [ + 'require', + 'exports', + 'module', + '../can-simple-dom', + 'steal-qunit', + '../lib/html-parser', + '../lib/void-map', + '../lib/html-serializer', + '../lib/default-tokenize' +], function (require, exports, module) { + var Document = require('../can-simple-dom'); + var QUnit = require('steal-qunit'); + var Parser = require('../lib/html-parser'); + var voidMap = require('../lib/void-map'); + var Serializer = require('../lib/html-serializer'); + var tokenize = require('../lib/default-tokenize'); + QUnit.module('can-simple-dom - Element with serialization and parsing'); + QUnit.test('document.implementation is supported (#23)', function () { + var document = new Document(); + document.__addSerializerAndParser(new Serializer(voidMap), new Parser(tokenize, document, voidMap)); + ok(document.implementation, 'implementation exists'); + var doc2 = document.implementation.createHTMLDocument(''); + ok(doc2.body, 'has a body'); + }); + QUnit.test('innerHTML supported', function () { + var document = new Document(); + document.__addSerializerAndParser(new Serializer(voidMap), new Parser(tokenize, document, voidMap)); + document.body.innerHTML = 'HI'; + QUnit.equal(document.body.firstChild.nodeName, 'SPAN'); + QUnit.equal(document.body.firstChild.className, 'bar'); + QUnit.equal(document.body.firstChild.firstChild.nodeValue, 'HI'); + QUnit.equal(document.body.innerHTML, 'HI'); + }); + QUnit.test('outerHTML supported', function () { + var document = new Document(); + document.__addSerializerAndParser(new Serializer(voidMap), new Parser(tokenize, document, voidMap)); + document.body.innerHTML = '
      HI
      '; + var item = document.getElementById('item'); + QUnit.equal(item.outerHTML, '
      HI
      ', 'getter'); + item.outerHTML = ''; + QUnit.equal(document.body.innerHTML, '', 'setter'); + }); +}); +/*can-simple-dom@1.4.2#test/element-event-test*/ +define('can-simple-dom@1.4.2#test/element-event-test', [ + 'require', + 'exports', + 'module', + '../lib/document', + '../lib/html-serializer', + '../lib/void-map', + './support', + 'steal-qunit' +], function (require, exports, module) { + var Document = require('../lib/document'); + var Serializer = require('../lib/html-serializer'); + var voidMap = require('../lib/void-map'); + var _support = require('./support'); + var element = _support.element; + var fragment = _support.fragment; + var text = _support.text; + var QUnit = require('steal-qunit'); + QUnit.module('can-simple-dom - Event'); + QUnit.test('basic bubbling', 4, function (assert) { + var document = new Document(); + var elem = document.createElement('div'); + document.body.appendChild(elem); + document.addEventListener('foo', function (event) { + assert.strictEqual(event.currentTarget, document, 'document current target'); + }); + document.documentElement.addEventListener('foo', function (event) { + assert.strictEqual(event.currentTarget, document.documentElement, 'documentElement current target'); + }); + document.body.addEventListener('foo', function (event) { + assert.strictEqual(event.currentTarget, document.body, 'body current target'); + }); + elem.addEventListener('foo', function (event) { + assert.strictEqual(event.currentTarget, elem, 'elem current target'); + }); + document.body.appendChild(elem); + var ev = document.createEvent('HTMLEvents'); + ev.initEvent('foo', true, false); + elem.dispatchEvent(ev); + }); + QUnit.test('stop propagation', 2, function (assert) { + var document = new Document(); + var elem = document.createElement('div'); + document.body.appendChild(elem); + document.addEventListener('foo', function (event) { + assert.strictEqual(event.currentTarget, document, 'document current target'); + }); + document.documentElement.addEventListener('foo', function (event) { + assert.strictEqual(event.currentTarget, document.documentElement, 'documentElement current target'); + }); + document.body.addEventListener('foo', function (event) { + assert.strictEqual(event.currentTarget, document.body, 'body current target'); + event.stopPropagation(); + }); + elem.addEventListener('foo', function (event) { + assert.strictEqual(event.currentTarget, elem, 'elem current target'); + }); + document.body.appendChild(elem); + var ev = document.createEvent('HTMLEvents'); + ev.initEvent('foo', true, false); + elem.dispatchEvent(ev); + }); + QUnit.test('initEvent without bubbling', 2, function (assert) { + var document = new Document(); + var elem = document.createElement('div'); + document.body.appendChild(elem); + document.body.addEventListener('foo', function (event) { + assert.strictEqual(event.currentTarget, document.body, 'body current target'); + event.stopPropagation(); + }); + elem.addEventListener('foo', function (event) { + assert.strictEqual(event.currentTarget, elem, 'elem current target'); + }); + elem.addEventListener('foo', function (event) { + assert.strictEqual(event.currentTarget, elem, 'elem current target'); + }); + document.body.appendChild(elem); + var ev = document.createEvent('HTMLEvents'); + ev.initEvent('foo', false, false); + elem.dispatchEvent(ev); + }); + QUnit.test('this inside event handler', function (assert) { + var document = new Document(); + var elem = document.createElement('div'); + document.body.appendChild(elem); + elem.addEventListener('foo', function () { + assert.equal(this, elem, 'this is the element'); + }); + var ev = document.createEvent('HTMLEvents'); + ev.initEvent('foo', true, false); + elem.dispatchEvent(ev); + }); + QUnit.test('deduplicate event handlers', function (assert) { + var done = assert.async(); + var document = new Document(); + var elem = document.createElement('div'); + document.body.appendChild(elem); + var handler = function () { + assert.ok(true, 'event dispatched'); + done(); + }; + elem.addEventListener('foo', handler); + elem.addEventListener('foo', handler); + var ev = document.createEvent('HTMLEvents'); + ev.initEvent('foo', true, false); + elem.dispatchEvent(ev); + }); +}); +/*can-simple-dom@1.4.2#test/parser-test*/ +define('can-simple-dom@1.4.2#test/parser-test', [ + 'require', + 'exports', + 'module', + './support', + '../lib/html-parser', + '../lib/void-map', + '../lib/default-tokenize', + 'steal-qunit' +], function (require, exports, module) { + var _support = require('./support'); + var document = _support.document; + var Parser = require('../lib/html-parser'); + var voidMap = require('../lib/void-map'); + var tokenize = require('../lib/default-tokenize'); + var QUnit = require('steal-qunit'); + QUnit.module('can-simple-dom - Basic HTML parsing', { + beforeEach: function () { + this.parser = new Parser(tokenize, document, voidMap); + } + }); + QUnit.test('simple parse', function (assert) { + var fragment = this.parser.parse('
      Hello
      '); + assert.ok(fragment); + var node = fragment.firstChild; + assert.ok(node); + assert.equal(node.nodeType, 1); + assert.equal(node.nodeName.toLowerCase(), 'div'); + assert.ok(node.firstChild); + assert.equal(node.firstChild.nodeType, 3); + assert.equal(node.firstChild.nodeValue, 'Hello'); + }); + QUnit.test('nested parse', function (assert) { + var fragment = this.parser.parse('text before
      Hello
      text between
      World
      text after'); + assert.ok(fragment); + var node = fragment.firstChild; + assert.ok(node); + assert.equal(node.nodeType, 3); + assert.equal(node.nodeValue, 'text before'); + node = node.nextSibling; + assert.ok(node); + assert.equal(node.nodeType, 1); + assert.equal(node.nodeName, 'DIV'); + assert.ok(node.firstChild); + assert.equal(node.firstChild.nodeType, 3); + assert.equal(node.firstChild.nodeValue, 'Hello'); + node = node.nextSibling; + assert.ok(node); + assert.equal(node.nodeType, 3); + assert.equal(node.nodeValue, 'text between'); + node = node.nextSibling; + assert.ok(node); + assert.equal(node.nodeType, 1); + assert.equal(node.nodeName, 'DIV'); + var expectedValues = { + id: 'foo', + title: 'Hello World' + }; + assert.equal(node.attributes.length, 2); + assert.equal(node.attributes[0].value, expectedValues[node.attributes[0].name]); + assert.equal(node.attributes[1].value, expectedValues[node.attributes[1].name]); + assert.equal(node.attributes.length, 2); + assert.ok(node.firstChild); + assert.equal(node.firstChild.nodeType, 3); + assert.equal(node.firstChild.nodeValue, 'World'); + node = node.nextSibling; + assert.ok(node); + assert.equal(node.nodeType, 3); + assert.equal(node.nodeValue, 'text after'); + }); + QUnit.test('void tags', function (assert) { + var fragment = this.parser.parse('
      Hello
      World
      '); + assert.ok(fragment); + var node = fragment.firstChild; + assert.ok(node); + assert.equal(node.nodeType, 1); + assert.equal(node.nodeName, 'DIV'); + node = node.firstChild; + assert.ok(node); + assert.equal(node.nodeType, 3); + assert.equal(node.nodeValue, 'Hello'); + node = node.nextSibling; + assert.ok(node); + assert.equal(node.nodeType, 1); + assert.equal(node.nodeName, 'BR'); + node = node.nextSibling; + assert.ok(node); + assert.equal(node.nodeType, 3); + assert.equal(node.nodeValue, 'World'); + node = node.nextSibling; + assert.ok(node); + assert.equal(node.nodeType, 1); + assert.equal(node.nodeName, 'IMG'); + assert.equal(node.getAttribute('src'), 'http://example.com/image.png?foo=bar&bar=foo'); + assert.equal(node.nextSibling, null); + }); + QUnit.test('node attribute charater encode', function (assert) { + var fragment = this.parser.parse('
      '); + assert.ok(fragment); + var node = fragment.firstChild; + assert.ok(node); + assert.equal(node.nodeType, 1); + assert.equal(node.nodeName, 'DIV'); + var attibutes = node.attributes; + assert.ok(attibutes.length); + var title = attibutes[0]; + assert.equal(title.name, 'title'); + assert.equal(title.value, ' foo & bar & baz < buz > biz'); + }); +}); +/*can-simple-dom@1.4.2#test/style-test*/ +define('can-simple-dom@1.4.2#test/style-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + '../lib/document/style' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var CSSStyleDeclaration = require('../lib/document/style'); + QUnit.module('can-simple-dom - CSStyleDeclaration'); + QUnit.test('cssText is enumerable', function () { + var proto = CSSStyleDeclaration.prototype; + var descriptor = Object.getOwnPropertyDescriptor(proto, 'cssText'); + QUnit.equal(descriptor.enumerable, true, 'it is enumerable'); + }); + QUnit.test('cssText is configurable', function () { + var proto = CSSStyleDeclaration.prototype; + var descriptor = Object.getOwnPropertyDescriptor(proto, 'cssText'); + QUnit.equal(descriptor.configurable, true, 'it is configurable'); + }); + QUnit.test('getPropertyValue must be a function', function () { + var proto = CSSStyleDeclaration.prototype; + QUnit.equal(typeof proto.getPropertyValue, 'function', 'it is a function'); + }); +}); +/*can-simple-dom@1.4.2#test/test*/ +define('can-simple-dom@1.4.2#test/test', [ + 'require', + 'exports', + 'module', + './document-test', + './element-test', + './serializer-test', + './element-sp-test', + './element-event-test', + './parser-test', + './style-test' +], function (require, exports, module) { + require('./document-test'); + require('./element-test'); + require('./serializer-test'); + require('./element-sp-test'); + require('./element-event-test'); + require('./parser-test'); + require('./style-test'); +}); +/*can-simple-observable@2.4.1#can-simple-observable-test*/ +define('can-simple-observable@2.4.1#can-simple-observable-test', [ + 'require', + 'exports', + 'module', + '@steal', + 'steal-qunit', + 'can-symbol', + 'can-simple-observable', + 'can-reflect', + 'can-observation-recorder' +], function (require, exports, module) { + var steal = require('@steal'); + var QUnit = require('steal-qunit'); + var canSymbol = require('can-symbol'); + var SimpleObservable = require('can-simple-observable'); + var canReflect = require('can-reflect'); + var ObservationRecorder = require('can-observation-recorder'); + var getChangesSymbol = canSymbol.for('can.getChangesDependencyRecord'); + var skipProduction = steal.isEnv('production') ? QUnit.skip : QUnit.test; + QUnit.module('can-simple-observable'); + QUnit.test('basics', function () { + expect(5); + var obs = new SimpleObservable('one'); + QUnit.equal(canReflect.getValue(obs), 'one', 'getValue'); + canReflect.setValue(obs, 'two'); + ObservationRecorder.start(); + QUnit.equal(canReflect.getValue(obs), 'two', 'setValue'); + var dependencies = ObservationRecorder.stop(); + QUnit.ok(dependencies.valueDependencies.has(obs), 'was recorded'); + var handler = function (newValue) { + QUnit.equal(newValue, 'three', 'onValue'); + }; + canReflect.onValue(obs, handler); + canReflect.setValue(obs, 'three'); + canReflect.offValue(obs, handler); + canReflect.setValue(obs, 'four'); + QUnit.equal(canReflect.getValue(obs), 'four', 'getValue after offValue'); + }); + QUnit.test('basics with .value', function () { + expect(5); + var obs = new SimpleObservable('one'); + QUnit.equal(obs.value, 'one', 'getValue'); + obs.value = 'two'; + ObservationRecorder.start(); + QUnit.equal(obs.value, 'two', 'setValue'); + var dependencies = ObservationRecorder.stop(); + QUnit.ok(dependencies.valueDependencies.has(obs), 'was recorded'); + var handler = function (newValue) { + QUnit.equal(newValue, 'three', 'onValue'); + }; + canReflect.onValue(obs, handler); + obs.value = 'three'; + canReflect.offValue(obs, handler); + obs.value = 'four'; + QUnit.equal(obs.value, 'four', 'getValue after offValue'); + }); + skipProduction('log observable changes', function (assert) { + var done = assert.async(); + var obs = new SimpleObservable('one'); + obs.log(); + assert.expect(2); + obs._log = function (previous, current) { + assert.equal(current, 'two', 'should get current value'); + assert.equal(previous, 'one', 'should get previous value'); + done(); + }; + canReflect.setValue(obs, 'two'); + }); + skipProduction('getWhatIChange works', function (assert) { + var one = new SimpleObservable('one'); + var two = new SimpleObservable('two'); + var handler = function handler() { + two.set('three'); + }; + var dependencyRecord = { valueDependencies: new Set([two]) }; + handler[getChangesSymbol] = function () { + return dependencyRecord; + }; + canReflect.onValue(one, handler); + assert.deepEqual(canReflect.getWhatIChange(one).mutate, dependencyRecord); + }); +}); +/*can-stache-key@1.4.0#can-stache-key-test*/ +define('can-stache-key@1.4.0#can-stache-key-test', [ + 'require', + 'exports', + 'module', + 'can-stache-key', + 'steal-qunit', + 'can-observation', + 'can-event-queue/map/map', + 'can-simple-observable', + 'can-test-helpers', + 'can-observation-recorder', + 'can-simple-map', + 'can-reflect' +], function (require, exports, module) { + var observeReader = require('can-stache-key'); + var QUnit = require('steal-qunit'); + var Observation = require('can-observation'); + var eventQueue = require('can-event-queue/map/map'); + var SimpleObservable = require('can-simple-observable'); + var testHelpers = require('can-test-helpers'); + var ObservationRecorder = require('can-observation-recorder'); + var SimpleMap = require('can-simple-map'); + var canReflect = require('can-reflect'); + QUnit.module('can-stache-key', {}); + test('can read a promise (#179)', function () { + var data = { + promise: new Promise(function (resolve) { + setTimeout(function () { + resolve('Something'); + }, 2); + }) + }; + var calls = 0; + var c = new Observation(function () { + return observeReader.read(data, observeReader.reads('promise.value')).value; + }); + canReflect.onValue(c, function (newVal, oldVal) { + calls++; + equal(calls, 1, 'only one call'); + equal(newVal, 'Something', 'new value'); + equal(oldVal, undefined, 'oldVal'); + start(); + }); + stop(); + }); + test('can.Compute.read can read a promise-like (#82)', function () { + var data = { + promiseLike: { + then: function (resolve) { + setTimeout(function () { + resolve('Something'); + }, 2); + } + } + }; + var calls = 0; + var c = new Observation(function () { + return observeReader.read(data, observeReader.reads('promiseLike.value')).value; + }); + canReflect.onValue(c, function (newVal, oldVal) { + calls++; + equal(calls, 1, 'only one call'); + equal(newVal, 'Something', 'new value'); + equal(oldVal, undefined, 'oldVal'); + start(); + }); + stop(); + }); + test('can.compute.reads', function () { + deepEqual(observeReader.reads('@foo'), [{ + key: 'foo', + at: true + }]); + deepEqual(observeReader.reads('@foo.bar'), [ + { + key: 'foo', + at: true + }, + { + key: 'bar', + at: false + } + ]); + deepEqual(observeReader.reads('@foo\\.bar'), [{ + key: 'foo.bar', + at: true + }]); + deepEqual(observeReader.reads('foo.bar@zed'), [ + { + key: 'foo', + at: false + }, + { + key: 'bar', + at: false + }, + { + key: 'zed', + at: true + } + ]); + }); + test('able to read things like can-define', 3, function () { + var obj = eventQueue({}); + var prop = 'PROP'; + Object.defineProperty(obj, 'prop', { + get: function () { + ObservationRecorder.add(obj, 'prop'); + return prop; + }, + set: function (val) { + var old = prop; + prop = val; + this.dispatch('prop', prop, old); + } + }); + var data = { obj: obj }; + var c = new Observation(function () { + var value = observeReader.read(data, observeReader.reads('obj.prop'), { + foundObservable: function (obs, index) { + equal(obs, obj, 'got an observable'); + equal(index, 1, 'got the right index'); + } + }).value; + equal(value, 'PROP'); + }); + canReflect.onValue(c, function () { + }); + }); + test('foundObservable called with observable object (#7)', function () { + var map = new SimpleMap({ + isSaving: function () { + ObservationRecorder.add(this, '_saving'); + }, + addEventListener: function () { + } + }); + var c = new Observation(function () { + observeReader.read(map, observeReader.reads('isSaving'), { + foundObservable: function (obs) { + QUnit.equal(obs, map); + }, + callMethodsOnObservables: true + }); + }); + canReflect.onValue(c, function () { + }); + }); + test('can read from strings', function () { + var context = ' hi there '; + var result = observeReader.read(context, observeReader.reads('trim'), {}); + QUnit.equal(result.value(context), context.trim(context), 'trim method works'); + }); + test('read / write to SimpleMap', function () { + var map = new SimpleMap(); + var c = new Observation(function () { + var data = observeReader.read(map, observeReader.reads('value'), { + foundObservable: function (obs) { + QUnit.equal(obs, map, 'got map'); + } + }); + return data.value; + }); + canReflect.onValue(c, function (newVal) { + QUnit.equal(newVal, 1, 'got updated'); + }); + observeReader.write(map, 'value', 1); + }); + test('write deep in SimpleMap', function () { + var map = new SimpleMap(); + observeReader.write(map, 'foo', new SimpleMap()); + observeReader.write(map, 'foo.bar', 1); + QUnit.equal(map.get('foo').get('bar'), 1, 'value set'); + }); + test('write to compute in object', function () { + var value = 2; + var computeObject = {}; + canReflect.assignSymbols(computeObject, { + 'can.getValue': function () { + return value; + }, + 'can.setValue': function (newVal) { + value = newVal; + } + }); + var obj = { compute: computeObject }; + observeReader.write(obj, 'compute', 3); + QUnit.equal(value, 3, 'value set'); + }); + test('write to a map in a compute', function () { + var map = new SimpleMap({ complete: true }); + var computeObject = {}; + canReflect.assignSymbols(computeObject, { + 'can.getValue': function () { + return map; + }, + 'can.setValue': function (newVal) { + map = newVal; + } + }); + observeReader.write(computeObject, 'complete', false); + QUnit.equal(map.attr('complete'), false, 'value set'); + }); + QUnit.test('reads can be passed a number (can-stache#207)', function () { + var reads = observeReader.reads(0); + QUnit.deepEqual(reads, [{ + key: '0', + at: false + }], 'number converted to string'); + }); + QUnit.test('can read primitive numbers (#88)', function () { + var reads = observeReader.reads('num@toFixed'); + var toFixed = observeReader.read({ num: 5 }, reads, {}).value; + QUnit.equal(typeof toFixed, 'function', 'got to fixed'); + }); + test('it returns null when promise getter is null #2', function () { + var nullPromise = observeReader.read(null, observeReader.reads('value')); + QUnit.equal(typeof nullPromise, 'object'); + }); + QUnit.test('set onto observable objects and values', function () { + var map = new SimpleMap(); + observeReader.write({ map: map }, 'map', { a: 'b' }); + QUnit.equal(map.get('a'), 'b', 'merged'); + var simple = new SimpleObservable(); + observeReader.write({ simple: simple }, 'simple', 1); + QUnit.equal(simple.get(), 1); + }); + testHelpers.dev.devOnlyTest('functions are not called by read()', function () { + var func = function () { + QUnit.ok(false, 'method called'); + }; + var data = { func: func }; + var reads = observeReader.reads('func'); + observeReader.read(data, reads); + QUnit.ok(true); + }); + testHelpers.dev.devOnlyTest('a warning is given for `callMethodsOnObservables: true`', function () { + var teardown = testHelpers.dev.willWarn('can-stache-key: read() called with `callMethodsOnObservables: true`.'); + var func = function () { + QUnit.ok(true, 'method called'); + }; + var data = new SimpleMap({ func: func }); + var reads = observeReader.reads('func'); + observeReader.read(data, reads, { callMethodsOnObservables: true }); + QUnit.equal(teardown(), 1, 'warning displayed'); + }); + QUnit.test('writing to a null observable is ignored', function () { + observeReader.write({}, 'foo.bar', 'value'); + observeReader.write(null, 'bar', 'value'); + observeReader.write(null, 'foo.bar', 'value'); + QUnit.ok(true, 'all passed without error'); + }); + QUnit.test('parentHasKey and foundLastParent (#31)', function () { + var hasKeys = function (obj, keys) { + canReflect.assignSymbols(obj, { + 'can.hasKey': function (key) { + return keys.indexOf(key) > -1; + } + }); + }; + var def = { ghi: undefined }; + hasKeys(def, ['ghi']); + var abc = { def: def }; + hasKeys(abc, ['def']); + var parent = { abc: abc }; + hasKeys(parent, ['abc']); + var testCases = { + 'abc.def.ghi': { + parent: def, + value: undefined, + parentHasKey: true, + foundLastParent: true + }, + 'abc.def.jkl': { + parent: def, + value: undefined, + parentHasKey: false, + foundLastParent: true + }, + 'abc.ghi.ghi': { + parent: abc, + value: undefined, + parentHasKey: false, + foundLastParent: false + }, + 'def.ghi.jkl': { + parent: parent, + value: undefined, + parentHasKey: false, + foundLastParent: false + } + }; + var reads, actual, expected; + for (var key in testCases) { + reads = observeReader.reads(key); + actual = observeReader.read(parent, reads); + expected = testCases[key]; + QUnit.equal(actual.value, expected.value, key + '.value'); + QUnit.equal(actual.parent, expected.parent, key + '.parent'); + QUnit.equal(actual.parentHasKey, expected.parentHasKey, key + '.parentHasKey'); + QUnit.equal(actual.foundLastParent, expected.foundLastParent, key + '.foundLastParent'); + } + }); + QUnit.test('objHasKeyAtIndex doesn\'t handle non-object types correctly (#33)', function () { + var result = observeReader.read(47, observeReader.reads('toFixed')); + QUnit.equal(typeof result.value, 'function'); + QUnit.equal(result.parent, 47); + QUnit.equal(result.parentHasKey, true); + }); + QUnit.test('write to an object', function () { + var obj = {}; + observeReader.write(obj, 'value', 1); + QUnit.deepEqual(obj, { value: 1 }); + obj = { value: null }; + observeReader.write(obj, 'value', 1); + QUnit.deepEqual(obj, { value: 1 }); + }); +}); +/*can-symbol@1.6.1#can-symbol-test*/ +define('can-symbol@1.6.1#can-symbol-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-symbol' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var canSymbol = require('can-symbol'); + QUnit.module('can-symbol'); + QUnit.test('for and keyFor', function () { + var symbol = canSymbol.for('abc'); + QUnit.ok(canSymbol.for('abc') === canSymbol.for('abc')); + QUnit.equal(canSymbol.keyFor(symbol), 'abc', 'key for'); + }); + QUnit.test('can get/set symbols', function () { + var obj = {}; + var symbol1 = canSymbol('prop1'), symbol2 = canSymbol('prop2'); + obj[symbol1] = 'VALUE'; + QUnit.equal(obj[symbol1], 'VALUE', 'got value'); + Object.defineProperty(obj, symbol2, { value: 'DP-VALUE' }); + QUnit.equal(obj[symbol2], 'DP-VALUE', 'got define property value'); + }); +}); +/*can-validate-interface@1.0.2#index*/ +define('can-validate-interface@1.0.2#index', function (require, exports, module) { + 'use strict'; + function flatten(arrays) { + return arrays.reduce(function (ret, val) { + return ret.concat(val); + }, []); + } + function makeInterfaceValidator(interfacePropArrays) { + var props = flatten(interfacePropArrays); + return function (base) { + var missingProps = props.reduce(function (missing, prop) { + return prop in base ? missing : missing.concat(prop); + }, []); + return missingProps.length ? { + message: 'missing expected properties', + related: missingProps + } : undefined; + }; + } + module.exports = makeInterfaceValidator; +}); +/*can-validate-interface@1.0.2#test*/ +define('can-validate-interface@1.0.2#test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './index.js' +], function (require, exports, module) { + 'use strict'; + var QUnit = require('steal-qunit'); + var makeInterfaceValidator = require('./index.js'); + QUnit.module('can-validate-interface/makeInterfaceValidator'); + QUnit.test('basics', function () { + var dataMethods = [ + 'create', + 'read', + 'update', + 'delete' + ]; + var daoValidator = makeInterfaceValidator([ + dataMethods, + 'id' + ]); + var dao = { + create: function () { + }, + read: function () { + }, + update: function () { + }, + delete: function () { + } + }; + var errors = daoValidator(dao); + QUnit.deepEqual(errors, { + message: 'missing expected properties', + related: ['id'] + }); + dao.id = 10; + errors = daoValidator(dao); + QUnit.equal(errors, undefined); + }); +}); +/*can-view-live@4.2.7#test/html-test*/ +define('can-view-live@4.2.7#test/html-test', [ + 'require', + 'exports', + 'module', + 'can-view-live', + 'can-define/list/list', + 'can-observation', + 'steal-qunit', + 'can-simple-observable', + 'can-view-nodelist', + 'can-test-helpers', + 'can-dom-mutate', + 'can-reflect-dependencies', + 'can-symbol', + 'can-fragment', + 'can-queues' +], function (require, exports, module) { + var live = require('can-view-live'); + var DefineList = require('can-define/list/list'); + var Observation = require('can-observation'); + var QUnit = require('steal-qunit'); + var SimpleObservable = require('can-simple-observable'); + var NodeLists = require('can-view-nodelist'); + var testHelpers = require('can-test-helpers'); + var domMutate = require('can-dom-mutate'); + var canReflectDeps = require('can-reflect-dependencies'); + var canSymbol = require('can-symbol'); + var fragment = require('can-fragment'); + var queues = require('can-queues'); + QUnit.module('can-view-live.html'); + test('basics', function () { + var div = document.createElement('div'), span = document.createElement('span'); + div.appendChild(span); + var items = new DefineList([ + 'one', + 'two' + ]); + var html = new Observation(function itemsHTML() { + var html = ''; + items.forEach(function (item) { + html += ''; + }); + return html; + }); + live.html(span, html, div); + equal(div.getElementsByTagName('label').length, 2); + items.push('three'); + equal(div.getElementsByTagName('label').length, 3); + }); + test('html live binding handles getting a function from a compute', 5, function () { + var handler = function (el) { + ok(true, 'called handler'); + equal(el.nodeType, 3, 'got a placeholder'); + }; + var div = document.createElement('div'), placeholder = document.createTextNode(''); + div.appendChild(placeholder); + var count = new SimpleObservable(0); + var html = new Observation(function () { + if (count.get() === 0) { + return '

      Hello World

      '; + } else { + return handler; + } + }); + live.html(placeholder, html, div); + equal(div.getElementsByTagName('h1').length, 1, 'got h1'); + count.set(1); + equal(div.getElementsByTagName('h1').length, 0, 'got h1'); + count.set(0); + equal(div.getElementsByTagName('h1').length, 1, 'got h1'); + }); + QUnit.test('Works with Observations - .html', function () { + var div = document.createElement('div'), span = document.createElement('span'); + div.appendChild(span); + var items = new DefineList([ + 'one', + 'two' + ]); + var html = new Observation(function () { + var html = ''; + items.forEach(function (item) { + html += ''; + }); + return html; + }); + live.html(span, html, div); + equal(div.getElementsByTagName('label').length, 2); + items.push('three'); + equal(div.getElementsByTagName('label').length, 3); + }); + test('html live binding handles objects with can.viewInsert symbol', 2, function (assert) { + var div = document.createElement('div'); + var options = {}; + var placeholder = document.createTextNode('Placeholder text'); + div.appendChild(placeholder); + var html = new Observation(function () { + var d = {}; + d[canSymbol.for('can.viewInsert')] = function () { + assert.equal(arguments[0], options, 'options were passed to symbol function'); + return document.createTextNode('Replaced text'); + }; + return d; + }); + live.html(placeholder, html, div, options); + assert.equal(div.textContent, 'Replaced text', 'symbol function called'); + }); + testHelpers.dev.devOnlyTest('child elements must disconnect before parents can re-evaluate', 1, function () { + var observable = new SimpleObservable('value'); + var childObservation = new Observation(function child() { + QUnit.ok(true, 'called child content once'); + observable.get(); + return 'CHILD CONTENT'; + }, null, { priority: 1 }); + var htmlNodeList = []; + var parentObservation = new Observation(function parent() { + var result = observable.get(); + if (result === 'value') { + var childTextNode = document.createTextNode(''); + var childFrag = document.createDocumentFragment(); + childFrag.appendChild(childTextNode); + var nodeList = [childTextNode]; + NodeLists.register(nodeList, null, htmlNodeList, true); + live.html(childTextNode, childObservation, null, nodeList); + return childFrag; + } else { + return 'NEW CONTENT'; + } + }, null, { priority: 0 }); + var parentTextNode = document.createTextNode(''); + var div = document.createElement('div'); + div.appendChild(parentTextNode); + htmlNodeList.push(parentTextNode); + NodeLists.register(htmlNodeList, function () { + }, true, true); + live.html(parentTextNode, parentObservation, div, htmlNodeList); + observable.set('VALUE'); + }); + testHelpers.dev.devOnlyTest('can-reflect-dependencies', function (assert) { + var done = assert.async(); + assert.expect(3); + var div = document.createElement('div'), span = document.createElement('span'); + div.appendChild(span); + document.body.appendChild(div); + var html = new Observation(function () { + return '

      Hello

      '; + }); + live.html(span, html, div); + assert.deepEqual(canReflectDeps.getDependencyDataOf(div).whatChangesMe.mutate.valueDependencies, new Set([html]), 'whatChangesMe(
      ) shows the observation'); + assert.deepEqual(canReflectDeps.getDependencyDataOf(html).whatIChange.derive.valueDependencies, new Set([div]), 'whatChangesMe() shows the div'); + var undo = domMutate.onNodeRemoval(div, function checkTeardown() { + undo(); + assert.equal(typeof canReflectDeps.getDependencyDataOf(div), 'undefined', 'dependencies should be clear out when elements is removed'); + done(); + }); + div.parentNode.removeChild(div); + }); + QUnit.test('.html works inside a .list (can-stache#542)', function () { + var div = document.createElement('div'), span = document.createElement('span'); + div.appendChild(span); + var itemNodeList = NodeLists.register([span]); + var listNodeList = NodeLists.register([itemNodeList]); + var content = new SimpleObservable(fragment('

      Hello

      ')); + live.html(span, content, div, itemNodeList); + queues.batch.start(); + content.set(fragment('Goodbye')); + queues.domUIQueue.enqueue(function () { + var itemNodeList = listNodeList[0]; + QUnit.equal(div.firstChild, itemNodeList[0], 'the DOM and nodeList should be in sync'); + }); + queues.batch.stop(); + }); + QUnit.test('.html works if it is enqueued twice', function () { + var div = fragment('
      PLACEHOLDER
      ').firstChild; + var html = new SimpleObservable(fragment('

      1

      ')); + live.html(div.firstChild, html, div); + queues.batch.start(); + queues.domUIQueue.enqueue(function setHTMLTO3() { + html.set(fragment('

      3

      ')); + }, null, []); + html.set(fragment('

      2

      ')); + queues.batch.stop(); + QUnit.ok(true, 'got here without an error'); + QUnit.deepEqual(div.innerHTML.toLowerCase(), '

      3

      '); + }); +}); +/*can-view-live@4.2.7#lib/patcher*/ +define('can-view-live@4.2.7#lib/patcher', [ + 'require', + 'exports', + 'module', + 'can-diff/patcher/patcher' +], function (require, exports, module) { + 'use strict'; + var Patcher = require('can-diff/patcher/patcher'); + module.exports = Patcher; +}); +/*can-view-live@4.2.7#test/patcher-test*/ +define('can-view-live@4.2.7#test/patcher-test', [ + 'require', + 'exports', + 'module', + 'can-define/list/list', + 'steal-qunit', + 'can-symbol', + '../lib/patcher', + 'can-simple-observable' +], function (require, exports, module) { + var DefineList = require('can-define/list/list'); + var QUnit = require('steal-qunit'); + var canSymbol = require('can-symbol'); + var Patcher = require('../lib/patcher'); + var SimpleObservable = require('can-simple-observable'); + QUnit.module('can-view-live patcher', { + setup: function () { + this.fixture = document.getElementById('qunit-fixture'); + } + }); + QUnit.test('multiple lists can be updated at once', 2, function () { + var list = new DefineList([ + 'a', + 'b' + ]); + var p1 = new Patcher(list), p2 = new Patcher(list); + p1[canSymbol.for('can.onPatches')](function () { + QUnit.ok(true, 'called p1'); + }); + p2[canSymbol.for('can.onPatches')](function () { + QUnit.ok(true, 'called p2'); + }); + list.push('c'); + }); + QUnit.test('undefined value won\'t error', 1, function () { + var undfinedObservable = new SimpleObservable(undefined); + var pu = new Patcher(undfinedObservable); + pu[canSymbol.for('can.onPatches')](function () { + QUnit.ok(true, 'called pu'); + }); + undfinedObservable.set('a'); + }); +}); +/*can-view-live@4.2.7#test/list-test*/ +define('can-view-live@4.2.7#test/list-test', [ + 'require', + 'exports', + 'module', + 'can-view-live', + 'can-define/list/list', + 'can-observation', + 'steal-qunit', + 'can-simple-observable', + 'can-simple-map', + 'can-reflect', + 'can-queues', + 'can-fragment', + 'can-view-nodelist', + 'can-dom-mutate', + 'can-dom-mutate/node', + 'can-symbol', + 'can-test-helpers', + 'can-reflect-dependencies', + 'can-globals' +], function (require, exports, module) { + (function (global, require, exports, module) { + var live = require('can-view-live'); + var DefineList = require('can-define/list/list'); + var Observation = require('can-observation'); + var QUnit = require('steal-qunit'); + var SimpleObservable = require('can-simple-observable'); + var SimpleMap = require('can-simple-map'); + var canReflect = require('can-reflect'); + var queues = require('can-queues'); + var fragment = require('can-fragment'); + var NodeLists = require('can-view-nodelist'); + var domMutate = require('can-dom-mutate'); + var domMutateNode = require('can-dom-mutate/node'); + var canSymbol = require('can-symbol'); + var testHelpers = require('can-test-helpers'); + var canReflectDeps = require('can-reflect-dependencies'); + var globals = require('can-globals'); + function afterMutation(cb) { + var doc = globals.getKeyValue('document'); + var div = doc.createElement('div'); + var undo = domMutate.onNodeInsertion(div, function () { + undo(); + doc.body.removeChild(div); + setTimeout(cb, 5); + }); + setTimeout(function () { + domMutateNode.appendChild.call(doc.body, div); + }, 10); + } + QUnit.module('can-view-live.list', { + setup: function () { + this.fixture = document.getElementById('qunit-fixture'); + } + }); + QUnit.test('basics', function () { + var div = document.createElement('div'), list = new DefineList([ + 'sloth', + 'bear' + ]), template = function (animal) { + return ' ' + animal.get() + ''; + }; + div.innerHTML = 'my fav animals: !'; + var el = div.getElementsByTagName('span')[0]; + live.list(el, list, template, {}); + equal(div.getElementsByTagName('label').length, 2, 'There are 2 labels'); + div.getElementsByTagName('label')[0].myexpando = 'EXPANDO-ED'; + list.push('turtle'); + equal(div.getElementsByTagName('label')[0].myexpando, 'EXPANDO-ED', 'same expando'); + equal(div.getElementsByTagName('span')[2].innerHTML, 'turtle', 'turtle added'); + }); + QUnit.test('list within an Observation', 5, function () { + var div = document.createElement('div'), map = new SimpleMap({ + animals: new DefineList([ + 'bear', + 'turtle' + ]) + }), template = function (animal) { + return ' ' + animal.get() + ''; + }; + var listCompute = new Observation(function animalsFromMap() { + return map.attr('animals'); + }); + div.innerHTML = 'my fav animals: !'; + var el = div.getElementsByTagName('span')[0]; + live.list(el, listCompute, template, {}); + equal(div.getElementsByTagName('label').length, 2, 'There are 2 labels'); + div.getElementsByTagName('label')[0].myexpando = 'EXPANDO-ED'; + map.attr('animals').push('turtle'); + equal(div.getElementsByTagName('label')[0].myexpando, 'EXPANDO-ED', 'same expando'); + equal(div.getElementsByTagName('span')[2].innerHTML, 'turtle', 'turtle added'); + map.attr('animals', new DefineList([ + 'sloth', + 'bear', + 'turtle' + ])); + var spans = div.getElementsByTagName('span'); + equal(spans.length, 3, 'there are 3 spans'); + ok(!div.getElementsByTagName('label')[0].myexpando, 'no expando'); + }); + QUnit.test('.list within a observable value holding an Array list', function () { + var div = document.createElement('div'); + var template = function (num) { + return ' ' + num + ''; + }; + var arr = new SimpleObservable([ + 0, + 1 + ]); + div.innerHTML = 'my fav nums: !'; + var el = div.getElementsByTagName('span')[0]; + live.list(el, arr, template, {}); + equal(div.getElementsByTagName('label').length, 2, 'There are 2 labels'); + arr.set([ + 0, + 1, + 2 + ]); + var spans = div.getElementsByTagName('span'); + equal(spans.length, 3, 'there are 3 spans'); + }); + test('live.list should handle move patches', function (assert) { + var parent = document.createElement('div'); + var child = document.createElement('div'); + parent.appendChild(child); + var onPatchesHandler; + var list = [ + 'a', + 'b', + 'c' + ]; + canReflect.assignSymbols(list, { + 'can.onPatches': function (handler) { + onPatchesHandler = handler; + } + }); + var template = function (num) { + return '' + num.get() + ''; + }; + live.list(child, list, template, {}); + list.shift(); + list.splice(1, 0, 'a'); + queues.batch.start(); + onPatchesHandler([{ + type: 'move', + fromIndex: 0, + toIndex: 1 + }]); + queues.batch.stop(); + assert.ok(true, 'The list should not blow up'); + var values = canReflect.toArray(parent.getElementsByTagName('span')).map(function (span) { + return span.innerHTML; + }); + QUnit.deepEqual(values, [ + 'b', + 'a', + 'c' + ]); + }); + QUnit.test('list and an falsey section (#1979)', function () { + var div = document.createElement('div'), template = function (num) { + return ' ' + num + ''; + }, falseyTemplate = function () { + return '

      NOTHING

      '; + }; + var listCompute = new SimpleObservable([ + 0, + 1 + ]); + div.innerHTML = 'my fav nums: !'; + var el = div.getElementsByTagName('span')[0]; + live.list(el, listCompute, template, {}, undefined, undefined, falseyTemplate); + equal(div.getElementsByTagName('label').length, 2, 'There are 2 labels'); + listCompute.set([]); + var spans = div.getElementsByTagName('span'); + equal(spans.length, 0, 'there are 0 spans'); + var ps = div.getElementsByTagName('p'); + equal(ps.length, 1, 'there is 1 p'); + listCompute.set([2]); + spans = div.getElementsByTagName('span'); + equal(spans.length, 1, 'there is 1 spans'); + ps = div.getElementsByTagName('p'); + equal(ps.length, 0, 'there is 1 p'); + }); + QUnit.test('list and an initial falsey section (#1979)', function () { + var div = document.createElement('div'), template = function (num) { + return ' ' + num + ''; + }, falseyTemplate = function () { + return '

      NOTHING

      '; + }; + var listCompute = new SimpleObservable([]); + div.innerHTML = 'my fav nums: !'; + var el = div.getElementsByTagName('span')[0]; + live.list(el, listCompute, template, {}, undefined, undefined, falseyTemplate); + var spans = div.getElementsByTagName('span'); + equal(spans.length, 0, 'there are 0 spans'); + var ps = div.getElementsByTagName('p'); + equal(ps.length, 1, 'there is 1 p'); + listCompute.set([2]); + spans = div.getElementsByTagName('span'); + equal(spans.length, 1, 'there is 1 spans'); + ps = div.getElementsByTagName('p'); + equal(ps.length, 0, 'there is 1 p'); + }); + test('list items should be correct even if renderer flushes batch (#8)', function () { + var partial = document.createElement('div'); + var placeholderElement = document.createElement('span'); + var list = new DefineList([ + 'one', + 'two' + ]); + var renderer = function (item) { + queues.flush(); + return '' + item.get() + ''; + }; + partial.appendChild(placeholderElement); + live.list(placeholderElement, list, renderer, {}); + equal(partial.getElementsByTagName('span').length, 2, 'should be two items'); + equal(partial.getElementsByTagName('span')[0].firstChild.data, 'one', 'list item 0 is "one"'); + equal(partial.getElementsByTagName('span')[1].firstChild.data, 'two', 'list item 1 is "two"'); + queues.batch.start(); + list.splice(0, 0, 'three'); + list.splice(2, 1); + queues.batch.stop(); + equal(partial.getElementsByTagName('span').length, 2, 'should be two items'); + equal(partial.getElementsByTagName('span')[0].firstChild.data, 'three', 'list item 0 is "three"'); + equal(partial.getElementsByTagName('span')[1].firstChild.data, 'one', 'list item 1 is "one"'); + }); + test('changing items in a live.list after it has been unregistered works (#55)', function () { + var map = new SimpleMap({ + show: true, + list: new DefineList(['one']) + }); + var htmlNodeList = canReflect.toArray(fragment('
      ').childNodes); + NodeLists.register(htmlNodeList, function () { + }, true); + var listNodeList = canReflect.toArray(fragment('
      ').childNodes); + NodeLists.register(listNodeList, function () { + }, htmlNodeList, true); + var listTextNode = document.createTextNode(''); + var listFrag = document.createDocumentFragment(); + listFrag.appendChild(listTextNode); + var htmlTextNode = document.createTextNode(''); + var div = document.createElement('div'); + div.appendChild(htmlTextNode); + var listObs = new Observation(function list() { + return map.attr('list'); + }, { priority: 2 }); + var listRenderer = function (item) { + Observation.temporarilyBind(item); + return item.get(); + }; + live.list(listTextNode, listObs, listRenderer, map, listTextNode.parentNode, listNodeList); + var htmlObservation = new Observation(function if_show_html() { + return map.attr('show') ? listFrag : undefined; + }, { priority: 1 }); + live.html(htmlTextNode, htmlObservation, htmlTextNode.parentNode, htmlNodeList); + queues.batch.start(); + map.attr('show', false); + map.attr('list').replace([ + 'two', + 'three' + ]); + queues.batch.stop(); + QUnit.ok(true, 'should not throw'); + }); + QUnit.test('Works with Observations - .list', function () { + var div = document.createElement('div'), map = new SimpleMap({ + animals: new DefineList([ + 'bear', + 'turtle' + ]) + }), template = function (animal) { + return ' ' + animal.get() + ''; + }; + var listObservation = new Observation(function () { + return map.attr('animals'); + }); + div.innerHTML = 'my fav animals: !'; + var el = div.getElementsByTagName('span')[0]; + live.list(el, listObservation, template, {}); + equal(div.getElementsByTagName('label').length, 2, 'There are 2 labels'); + div.getElementsByTagName('label')[0].myexpando = 'EXPANDO-ED'; + map.attr('animals').push('turtle'); + equal(div.getElementsByTagName('label')[0].myexpando, 'EXPANDO-ED', 'same expando'); + equal(div.getElementsByTagName('span')[2].innerHTML, 'turtle', 'turtle added'); + map.attr('animals', new DefineList([ + 'sloth', + 'bear', + 'turtle' + ])); + var spans = div.getElementsByTagName('span'); + equal(spans.length, 3, 'there are 3 spans'); + ok(!div.getElementsByTagName('label')[0].myexpando, 'no expando'); + }); + test('no memory leaks', function () { + var div = document.createElement('div'), map = new SimpleMap({ + animals: new DefineList([ + 'bear', + 'turtle' + ]) + }), template = function (animal) { + return ' ' + animal.get() + ''; + }; + var listObservation = new Observation(function () { + return map.attr('animals'); + }); + div.innerHTML = 'my fav animals: !'; + var el = div.getElementsByTagName('span')[0]; + this.fixture.appendChild(div); + var fixture = this.fixture; + live.list(el, listObservation, template, {}); + QUnit.stop(); + function checkHandlers() { + var handlers = map[canSymbol.for('can.meta')].handlers.get([]); + if (handlers.length === 0) { + equal(handlers.length, 0, 'there are no bindings'); + start(); + } else { + setTimeout(checkHandlers, 10); + } + } + setTimeout(function () { + domMutateNode.removeChild.call(fixture, div); + afterMutation(checkHandlers); + }, 10); + }); + testHelpers.dev.devOnlyTest('can-reflect-dependencies', function (assert) { + var done = assert.async(); + assert.expect(2); + var div = document.createElement('div'); + div.innerHTML = 'my fav animals: !'; + document.body.appendChild(div); + var el = div.getElementsByTagName('span')[0]; + var list = new DefineList([ + 'sloth', + 'bear' + ]); + var template = function (animal) { + return ' ' + animal.get() + ''; + }; + live.list(el, list, template, {}); + assert.deepEqual(canReflectDeps.getDependencyDataOf(div).whatChangesMe.mutate.valueDependencies, new Set([list])); + var undo = domMutate.onNodeRemoval(div, function checkTeardown() { + undo(); + assert.equal(typeof canReflectDeps.getDependencyDataOf(div), 'undefined', 'dependencies should be cleared when parent node is removed'); + done(); + }); + div.parentNode.removeChild(div); + }); + test('no memory leaks with replacements (#93)', function () { + var div = document.createElement('div'), animals = new DefineList([ + 'bear', + 'turtle' + ]), template = function (animal) { + return ' ' + animal.get() + ''; + }; + div.innerHTML = 'my fav animals: !'; + var htmlNodeList = canReflect.toArray(div.childNodes); + NodeLists.register(htmlNodeList, function () { + }, true); + var el = div.getElementsByTagName('span')[0]; + this.fixture.appendChild(div); + var nodeList = [el]; + NodeLists.register(nodeList, function () { + }, htmlNodeList); + live.list(el, animals, template, {}, this.fixture, nodeList); + QUnit.deepEqual(nodeList.replacements, [], 'no replacements'); + animals.push('foo'); + QUnit.deepEqual(nodeList.replacements, [], 'no replacements'); + animals.shift(); + QUnit.deepEqual(nodeList.replacements, [], 'no replacements'); + }); + test('Undefined list and teardown', function () { + var div = document.createElement('div'), map = new SimpleMap({ items: undefined }), template = function () { + return ''; + }; + var listObservation = new Observation(function () { + return map.attr('items'); + }); + div.innerHTML = 'my fav animals: !'; + var el = div.getElementsByTagName('span')[0]; + this.fixture.appendChild(div); + var fixture = this.fixture; + live.list(el, listObservation, template, {}); + QUnit.stop(); + function checkHandlers() { + QUnit.ok(true, 'was able to teardown'); + QUnit.start(); + } + setTimeout(function () { + domMutateNode.removeChild.call(fixture, div); + afterMutation(checkHandlers); + }, 10); + }); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-view-live@4.2.7#test/text-test*/ +define('can-view-live@4.2.7#test/text-test', [ + 'require', + 'exports', + 'module', + 'can-view-live', + 'can-observation', + 'steal-qunit', + 'can-simple-observable', + 'can-dom-mutate', + 'can-dom-mutate/node', + 'can-view-nodelist', + 'can-test-helpers', + 'can-reflect-dependencies', + 'can-globals' +], function (require, exports, module) { + (function (global, require, exports, module) { + var live = require('can-view-live'); + var Observation = require('can-observation'); + var QUnit = require('steal-qunit'); + var SimpleObservable = require('can-simple-observable'); + var domMutate = require('can-dom-mutate'); + var domMutateNode = require('can-dom-mutate/node'); + var nodeLists = require('can-view-nodelist'); + var testHelpers = require('can-test-helpers'); + var canReflectDeps = require('can-reflect-dependencies'); + var canGlobals = require('can-globals'); + QUnit.module('can-view-live.text', { + setup: function () { + this.fixture = document.getElementById('qunit-fixture'); + } + }); + var esc = function (str) { + return str.replace(//g, '>'); + }; + QUnit.test('text', function () { + var div = document.createElement('div'), span = document.createElement('span'); + div.appendChild(span); + var value = new SimpleObservable([ + 'one', + 'two' + ]); + var text = new Observation(function html() { + var html = ''; + value.get().forEach(function (item) { + html += ''; + }); + return html; + }); + live.text(span, text, div); + equal(div.innerHTML, esc('')); + value.set([ + 'one', + 'two', + 'three' + ]); + equal(div.innerHTML, esc('')); + }); + QUnit.test('text binding is memory safe (#666)', function () { + nodeLists.nodeMap.clear(); + var div = document.createElement('div'), span = document.createElement('span'), text = new Observation(function () { + return 'foo'; + }); + div.appendChild(span); + domMutateNode.appendChild.call(this.fixture, div); + live.text(span, text, div); + domMutateNode.removeChild.call(this.fixture, div); + stop(); + setTimeout(function () { + ok(!nodeLists.nodeMap.size, 'nothing in nodeMap'); + start(); + }, 100); + }); + testHelpers.dev.devOnlyTest('can-reflect-dependencies', function (assert) { + var done = assert.async(); + assert.expect(3); + var div = document.createElement('div'); + var span = document.createElement('span'); + div.appendChild(span); + document.body.appendChild(div); + var value = new SimpleObservable([ + 'one', + 'two' + ]); + var text = new Observation(function html() { + return value.get().map(function (item) { + return ''; + }).join(''); + }); + live.text(span, text, div); + assert.deepEqual(canReflectDeps.getDependencyDataOf(div).whatChangesMe.mutate.valueDependencies, new Set([text]), 'whatChangesMe(
      ) shows the observation'); + assert.deepEqual(canReflectDeps.getDependencyDataOf(text).whatIChange.mutate.valueDependencies, new Set([div]), 'whatChangesMe(observation) shows the
      '); + var undo = domMutate.onNodeRemoval(div, function checkTeardown() { + undo(); + assert.equal(typeof canReflectDeps.getDependencyDataOf(div), 'undefined', 'dependencies should be clear out when elements is removed'); + done(); + }); + div.parentNode.removeChild(div); + }); + QUnit.test('Removing the documentElement tears down correctly', function (assert) { + var done = assert.async(); + assert.expect(1); + var realDoc = canGlobals.getKeyValue('document'); + var doc = document.implementation.createHTMLDocument('testing'); + canGlobals.setKeyValue('document', doc); + var tn = doc.createTextNode('foo'); + domMutate.onNodeRemoval(doc.body, function () { + canGlobals.setKeyValue('document', realDoc); + assert.ok(true, 'Removal fired'); + done(); + }); + var text = new Observation(function () { + return 'foo'; + }); + domMutateNode.appendChild.call(doc.body, tn); + live.text(tn, text, doc.body); + domMutateNode.removeChild.call(doc, doc.documentElement); + }); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-view-live@4.2.7#test/attr-test*/ +define('can-view-live@4.2.7#test/attr-test', [ + 'require', + 'exports', + 'module', + 'can-view-live', + 'can-observation', + 'steal-qunit', + 'can-dom-mutate', + 'can-dom-mutate/node', + 'can-simple-observable', + 'can-test-helpers', + 'can-reflect-dependencies' +], function (require, exports, module) { + var live = require('can-view-live'); + var Observation = require('can-observation'); + var QUnit = require('steal-qunit'); + var domMutate = require('can-dom-mutate'); + var domMutateNode = require('can-dom-mutate/node'); + var SimpleObservable = require('can-simple-observable'); + var testHelpers = require('can-test-helpers'); + var canReflectDeps = require('can-reflect-dependencies'); + QUnit.module('can-view-live.attr', { + setup: function () { + this.fixture = document.getElementById('qunit-fixture'); + } + }); + QUnit.test('basics', function () { + var div = document.createElement('div'); + var firstValue = new SimpleObservable(null); + var first = new Observation(function () { + return firstValue.get() ? 'selected' : ''; + }); + var secondValue = new SimpleObservable(null); + var second = new Observation(function () { + return secondValue.get() ? 'active' : ''; + }); + var className = new Observation(function () { + return 'foo ' + first.get() + ' ' + second.get() + ' end'; + }); + live.attr(div, 'class', className); + equal(div.className, 'foo end'); + firstValue.set(true); + equal(div.className, 'foo selected end'); + secondValue.set(true); + equal(div.className, 'foo selected active end'); + firstValue.set(false); + equal(div.className, 'foo active end'); + }); + QUnit.test('specialAttribute with new line', function () { + var div = document.createElement('div'); + var style = new SimpleObservable('width: 50px;\nheight:50px;'); + live.attr(div, 'style', style); + equal(div.style.height, '50px'); + equal(div.style.width, '50px'); + }); + QUnit.test('can.live.attr works with non-string attributes (#1790)', function () { + var el = document.createElement('div'), attrCompute = new Observation(function () { + return 2; + }); + domMutateNode.setAttribute.call(el, 'value', 1); + live.attr(el, 'value', attrCompute); + ok(true, 'No exception thrown.'); + }); + testHelpers.dev.devOnlyTest('can-reflect-dependencies', function (assert) { + var done = assert.async(); + assert.expect(4); + var div = document.createElement('div'); + document.body.appendChild(div); + var id = new SimpleObservable('foo'); + var title = new SimpleObservable('something'); + live.attr(div, 'id', id); + live.attr(div, 'title', title); + assert.deepEqual(canReflectDeps.getDependencyDataOf(div).whatChangesMe.mutate.valueDependencies, new Set([ + id, + title + ]), 'getDependencyDataOf(
      ) should return the two SimpleObservables as dependencies'); + assert.deepEqual(canReflectDeps.getDependencyDataOf(id).whatIChange.derive.valueDependencies, new Set([div]), 'getDependencyDataOf(id) should return the
      as a dependency'); + assert.deepEqual(canReflectDeps.getDependencyDataOf(title).whatIChange.derive.valueDependencies, new Set([div]), 'getDependencyDataOf(title) should return the
      as a dependency'); + var undo = domMutate.onNodeRemoval(div, function checkTeardown() { + undo(); + assert.equal(typeof canReflectDeps.getDependencyDataOf(div), 'undefined', 'dependencies should be cleared out when elements is removed'); + done(); + }); + div.parentNode.removeChild(div); + }); + QUnit.test('can.live.attr works with value (#96)', function () { + var el = document.createElement('input'), attrObservable = new SimpleObservable('Hello'); + live.attr(el, 'value', attrObservable); + equal(el.value, 'Hello', 'Hello'); + attrObservable.set('Hi'); + equal(el.value, 'Hi', 'Hi'); + el.value = 'Hey'; + equal(el.value, 'Hey', 'Hey'); + attrObservable.set('Aloha'); + equal(el.value, 'Aloha', 'Aloha'); + }); +}); +/*can-view-live@4.2.7#test/attrs-test*/ +define('can-view-live@4.2.7#test/attrs-test', [ + 'require', + 'exports', + 'module', + 'can-view-live', + 'can-observation', + 'steal-qunit', + 'can-simple-observable', + 'can-queues', + 'can-dom-mutate', + 'can-dom-mutate/node', + 'can-test-helpers', + 'can-reflect-dependencies' +], function (require, exports, module) { + var live = require('can-view-live'); + var Observation = require('can-observation'); + var QUnit = require('steal-qunit'); + var SimpleObservable = require('can-simple-observable'); + var queues = require('can-queues'); + var domMutate = require('can-dom-mutate'); + var domMutateNode = require('can-dom-mutate/node'); + var testHelpers = require('can-test-helpers'); + var canReflectDeps = require('can-reflect-dependencies'); + QUnit.module('can-view-live.attrs', { + setup: function () { + this.fixture = document.getElementById('qunit-fixture'); + } + }); + QUnit.test('basics', function () { + var div = document.createElement('div'); + var property = new SimpleObservable('class'), value = new SimpleObservable('foo'); + var text = new Observation(function () { + var html = ''; + if (property.get() && value.get()) { + html += property.get() + '=\'' + value.get() + '\''; + } + return html; + }); + live.attrs(div, text); + equal(div.className, 'foo'); + property.set(null); + equal(div.className, ''); + queues.batch.start(); + property.set('foo'); + value.set('bar'); + queues.batch.stop(); + equal(div.getAttribute('foo'), 'bar'); + }); + QUnit.test('should remove `removed` events listener', function (assert) { + var done = assert.async(); + var onNodeRemoval = domMutate.onNodeRemoval; + domMutate.onNodeRemoval = function () { + assert.ok(true, 'addEventListener called'); + var disposal = onNodeRemoval.apply(null, arguments); + domMutate.onNodeRemoval = onNodeRemoval; + return function () { + assert.ok(true, 'disposal function was called'); + disposal(); + done(); + }; + }; + var div = document.createElement('div'); + var text = new SimpleObservable('hello'); + domMutateNode.appendChild.call(this.fixture, div); + live.attrs(div, text); + domMutateNode.removeChild.call(this.fixture, div); + }); + testHelpers.dev.devOnlyTest('can-reflect-dependencies', function (assert) { + var done = assert.async(); + assert.expect(3); + var div = document.createElement('div'); + document.body.appendChild(div); + var attr = new SimpleObservable('class'); + var value = new SimpleObservable('foo'); + var text = new Observation(function () { + var html = ''; + if (attr.get() && value.get()) { + html += attr.get() + '="' + value.get() + '"'; + } + return html; + }); + live.attrs(div, text); + assert.deepEqual(canReflectDeps.getDependencyDataOf(div).whatChangesMe.mutate.valueDependencies, new Set([text]), 'getDependencyDataOf(
      ) should return the observation as a dependency'); + assert.deepEqual(canReflectDeps.getDependencyDataOf(text).whatIChange.mutate.valueDependencies, new Set([div]), 'getDependencyDataOf(observation) should return the div as a dependency'); + var undo = domMutate.onNodeRemoval(div, function checkTeardown() { + undo(); + assert.equal(typeof canReflectDeps.getDependencyDataOf(div), 'undefined', 'dependencies should be cleared out when element is removed'); + done(); + }); + div.parentNode.removeChild(div); + }); + if (window.document && document.contains) { + QUnit.test('use document contains if possible', function (assert) { + var done = assert.async(); + var onNodeRemoval = domMutate.onNodeRemoval; + domMutate.onNodeRemoval = function () { + var disposal = onNodeRemoval.apply(null, arguments); + domMutate.onNodeRemoval = onNodeRemoval; + return function () { + disposal(); + done(); + }; + }; + var contains = document.contains; + document.contains = function () { + assert.ok(true, 'contains was called'); + var result = contains.apply(this, arguments); + document.contains = contains; + return result; + }; + var div = document.createElement('div'); + var text = new SimpleObservable('hello'); + domMutateNode.appendChild.call(this.fixture, div); + live.attrs(div, text); + domMutateNode.removeChild.call(this.fixture, div); + }); + } +}); +/*can-view-live@4.2.7#test/test*/ +define('can-view-live@4.2.7#test/test', [ + 'require', + 'exports', + 'module', + './html-test', + './patcher-test', + './list-test', + './text-test', + './attr-test', + './attrs-test' +], function (require, exports, module) { + require('./html-test'); + require('./patcher-test'); + require('./list-test'); + require('./text-test'); + require('./attr-test'); + require('./attrs-test'); +}); +/*can-view-model@4.0.1#can-view-model_test*/ +define('can-view-model@4.0.1#can-view-model_test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-view-model', + 'can-simple-map' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var viewModel = require('can-view-model'); + var SimpleMap = require('can-simple-map'); + QUnit.module('can-view-model'); + QUnit.test('basics', function () { + var el = document.createElement('div'); + viewModel(el, 'foo', 'bar'); + QUnit.equal(viewModel(el, 'foo'), 'bar'); + QUnit.ok(viewModel(el) instanceof SimpleMap, 'is SimpleMap'); + }); + QUnit.test('a selector can be passed as the first argument (#6)', function () { + var el = document.createElement('div'); + el.className = 'the-el'; + document.getElementById('qunit-fixture').appendChild(el); + viewModel('.the-el', 'foo', 'bar'); + QUnit.equal(viewModel('.the-el', 'foo'), 'bar'); + QUnit.ok(viewModel(el) instanceof SimpleMap, 'is can-map'); + }); + QUnit.test('set custom can-simple-map on element (#5)', function () { + var vm, elVm; + var CustomMap = SimpleMap.extend({}); + var el = document.createElement('div'); + document.getElementById('qunit-fixture').appendChild(el); + vm = new CustomMap({ foo: 'bar' }); + elVm = viewModel(el, vm); + QUnit.equal(viewModel(el, 'foo'), 'bar'); + }); + QUnit.test('Allow passing array like (jQuery) element', function () { + var $el = {}; + var el = document.createElement('div'); + el.className = 'the-el'; + $el[0] = el; + $el.length = 1; + document.getElementById('qunit-fixture').appendChild(el); + viewModel($el, 'foo', 'bar'); + QUnit.equal(viewModel('.the-el', 'foo'), 'bar', 'It reads view scope from html element'); + QUnit.equal(viewModel($el, 'foo'), 'bar', 'It reads view scope from array like (jQuery) element'); + QUnit.ok(viewModel(el) instanceof SimpleMap, 'is can-map'); + }); + QUnit.test('elements with length property not treated as arraylikes (#31)', function () { + var el = document.createElement('select'); + document.getElementById('qunit-fixture').appendChild(el); + QUnit.equal(el.length, 0, 'Select has length property (0 for empty)'); + QUnit.deepEqual(viewModel(el).get(), {}, 'viewModel created on empty select'); + var opt = document.createElement('option'); + el.appendChild(opt); + QUnit.equal(el.length, 1, 'Select has length 1'); + QUnit.deepEqual(viewModel(el).get(), {}, 'viewModel created on non-empty select'); + }); +}); +/*can-view-model@4.0.1#test/test*/ +define('can-view-model@4.0.1#test/test', [ + 'require', + 'exports', + 'module', + '../can-view-model_test' +], function (require, exports, module) { + require('../can-view-model_test'); +}); +/*can-view-nodelist@4.3.2#test/can-view-nodelist-test*/ +define('can-view-nodelist@4.3.2#test/can-view-nodelist-test', [ + 'require', + 'exports', + 'module', + 'can-view-nodelist', + 'can-fragment', + 'can-reflect', + 'steal-qunit' +], function (require, exports, module) { + var nodeLists = require('can-view-nodelist'); + var fragment = require('can-fragment'); + var canReflect = require('can-reflect'); + var QUnit = require('steal-qunit'); + QUnit.module('can-view-nodelist'); + test('unregisters child nodeLists', function () { + expect(4); + var spansFrag = fragment('12'); + var spansList = canReflect.toArray(spansFrag.childNodes); + nodeLists.register(spansList, function () { + ok(true, 'unregistered spansList'); + }); + var labelFrag = fragment(''); + var labelList = canReflect.toArray(labelFrag.childNodes); + nodeLists.register(labelList, function () { + ok(true, 'unregistered labelList'); + }); + var ifPreHookupFrag = fragment([ + '~', + '', + '-', + '' + ]), ifChildNodes = ifPreHookupFrag.childNodes, ifEls = canReflect.toArray(ifChildNodes); + nodeLists.replace([ifChildNodes[1]], spansFrag); + nodeLists.replace([ifChildNodes[4]], labelFrag); + var ifList = canReflect.toArray(ifPreHookupFrag.childNodes); + nodeLists.register(ifList, function () { + ok(true, 'unregistered ifList'); + }); + deepEqual(ifList, [ + ifEls[0], + spansList, + ifEls[2], + labelList + ]); + nodeLists.update(ifList, [document.createTextNode('empty')]); + QUnit.ok(labelList.isUnregistered, 'labelList was unregistered'); + }); +}); +/*can-view-parser@4.1.2#test/can-view-parser-test*/ +define('can-view-parser@4.1.2#test/can-view-parser-test', [ + 'require', + 'exports', + 'module', + 'can-view-parser', + 'steal-qunit', + 'can-log/dev/dev', + 'can-attribute-encoder', + 'can-test-helpers' +], function (require, exports, module) { + var parser = require('can-view-parser'); + var QUnit = require('steal-qunit'); + var canDev = require('can-log/dev/dev'); + var encoder = require('can-attribute-encoder'); + var testHelpers = require('can-test-helpers'); + QUnit.module('can-view-parser'); + var makeChecks = function (tests) { + var count = 0; + var makeCheck = function (name) { + return function () { + if (count >= tests.length) { + ok(false, 'called ' + name + ' with ' + JSON.stringify([].slice.call(arguments))); + } else { + var test = tests[count], args = test[1]; + equal(name, test[0], 'test ' + count + ' ' + name + '('); + for (var i = 0; i < args.length; i++) { + equal(arguments[i], args[i], i + 1 + ' arg -> ' + args[i]); + } + count++; + } + }; + }; + return { + start: makeCheck('start'), + end: makeCheck('end'), + close: makeCheck('close'), + attrStart: makeCheck('attrStart'), + attrEnd: makeCheck('attrEnd'), + attrValue: makeCheck('attrValue'), + chars: makeCheck('chars'), + comment: makeCheck('comment'), + special: makeCheck('special'), + done: makeCheck('done') + }; + }; + test('html to html', function () { + var tests = [ + [ + 'start', + [ + 'h1', + false + ] + ], + [ + 'attrStart', + ['id'] + ], + [ + 'attrValue', + ['foo'] + ], + [ + 'attrEnd', + ['id'] + ], + [ + 'special', + ['#if'] + ], + [ + 'special', + ['.'] + ], + [ + 'special', + ['/if'] + ], + [ + 'attrStart', + ['class'] + ], + [ + 'attrValue', + ['a'] + ], + [ + 'special', + ['foo'] + ], + [ + 'attrEnd', + ['class'] + ], + [ + 'end', + [ + 'h1', + false + ] + ], + [ + 'chars', + ['Hello '] + ], + [ + 'special', + ['message'] + ], + [ + 'chars', + ['!'] + ], + [ + 'close', + ['h1'] + ], + [ + 'done', + [] + ] + ]; + parser('

      Hello {{message}}!

      ', makeChecks(tests)); + }); + test('uppercase html to html', function () { + var tests = [ + [ + 'start', + [ + 'div', + false + ] + ], + [ + 'end', + [ + 'div', + false + ] + ], + [ + 'chars', + ['sibling'] + ], + [ + 'close', + ['div'] + ], + [ + 'start', + [ + 'div', + false + ] + ], + [ + 'end', + [ + 'div', + false + ] + ], + [ + 'chars', + ['sibling'] + ], + [ + 'close', + ['div'] + ], + [ + 'done', + [] + ] + ]; + parser('
      sibling
      sibling
      ', makeChecks(tests)); + }); + test('camelCase attributes stay untouched (svg) - #22', function () { + var tests = [ + [ + 'start', + [ + 'svg', + false + ] + ], + [ + 'attrStart', + ['viewBox'] + ], + [ + 'attrValue', + ['0 0 15 22'] + ], + [ + 'attrEnd', + ['viewBox'] + ], + [ + 'end', + [ + 'svg', + false + ] + ], + [ + 'close', + ['svg'] + ], + [ + 'done', + [] + ] + ]; + parser('', makeChecks(tests)); + }); + test('camelCase tags stay untouched (svg)', function () { + var tests = [ + [ + 'start', + [ + 'svg', + false + ] + ], + [ + 'end', + [ + 'svg', + false + ] + ], + [ + 'start', + [ + 'radialGradient', + false + ] + ], + [ + 'end', + [ + 'radialGradient', + false + ] + ], + [ + 'close', + ['radialGradient'] + ], + [ + 'close', + ['svg'] + ], + [ + 'done', + [] + ] + ]; + parser('', makeChecks(tests)); + }); + test('special in an attribute in an in-tag section', function () { + parser('
      ', makeChecks([ + [ + 'start', + [ + 'div', + false + ] + ], + [ + 'special', + ['#truthy'] + ], + [ + 'attrStart', + ['foo'] + ], + [ + 'special', + ['baz'] + ], + [ + 'attrEnd', + ['foo'] + ], + [ + 'special', + ['/truthy'] + ], + [ + 'end', + [ + 'div', + false + ] + ], + [ + 'close', + ['div'] + ], + [ + 'done', + [] + ] + ])); + }); + test('special with a custom attribute', function () { + parser('
      ', makeChecks([ + [ + 'start', + [ + 'div', + false + ] + ], + [ + 'special', + ['#attribute'] + ], + [ + 'special', + ['name'] + ], + [ + 'attrStart', + [''] + ], + [ + 'special', + ['value'] + ], + [ + 'attrEnd', + [''] + ], + [ + 'special', + ['/attribute'] + ], + [ + 'end', + [ + 'div', + false + ] + ], + [ + 'close', + ['div'] + ], + [ + 'done', + [] + ] + ])); + }); + test('single attribute value', function () { + parser('', makeChecks([ + [ + 'start', + [ + 'input', + true + ] + ], + [ + 'attrStart', + ['DISABLED'] + ], + [ + 'attrEnd', + ['DISABLED'] + ], + [ + 'end', + [ + 'input', + true + ] + ], + [ + 'done', + [] + ] + ])); + }); + test('trailing linebreaks in IE', function () { + parser('12345{{!\n This is a\n multi-line comment...\n}}67890\n', makeChecks([ + [ + 'chars', + ['12345'] + ], + [ + 'special', + ['!\n This is a\n multi-line comment...\n'] + ], + [ + 'chars', + ['67890\n'] + ], + [ + 'done', + [] + ] + ])); + }); + test('block are allowed inside anchor tags', function () { + parser('
      ', makeChecks([ + [ + 'start', + [ + 'a', + false + ] + ], + [ + 'end', + [ + 'a', + false + ] + ], + [ + 'start', + [ + 'div', + false + ] + ], + [ + 'end', + [ + 'div', + false + ] + ], + [ + 'close', + ['div'] + ], + [ + 'close', + ['a'] + ], + [ + 'done', + [] + ] + ])); + }); + test('anchors are allowed as children of inline elements - #2169', function () { + parser('', makeChecks([ + [ + 'start', + [ + 'span', + false + ] + ], + [ + 'end', + [ + 'span', + false + ] + ], + [ + 'start', + [ + 'a', + false + ] + ], + [ + 'end', + [ + 'a', + false + ] + ], + [ + 'close', + ['a'] + ], + [ + 'close', + ['span'] + ], + [ + 'done', + [] + ] + ])); + }); + test('inline tags encapsulate inner block elements', function () { + parser('
      ', makeChecks([ + [ + 'start', + [ + 'span', + false + ] + ], + [ + 'end', + [ + 'span', + false + ] + ], + [ + 'start', + [ + 'div', + false + ] + ], + [ + 'end', + [ + 'div', + false + ] + ], + [ + 'close', + ['div'] + ], + [ + 'close', + ['span'] + ], + [ + 'done', + [] + ] + ])); + parser('

      ', makeChecks([ + [ + 'start', + [ + 'em', + false + ] + ], + [ + 'end', + [ + 'em', + false + ] + ], + [ + 'start', + [ + 'h1', + false + ] + ], + [ + 'end', + [ + 'h1', + false + ] + ], + [ + 'close', + ['h1'] + ], + [ + 'close', + ['em'] + ], + [ + 'done', + [] + ] + ])); + }); + test('unordered lists will contain their list items', function () { + parser('
      ', makeChecks([ + [ + 'start', + [ + 'ul', + false + ] + ], + [ + 'end', + [ + 'ul', + false + ] + ], + [ + 'start', + [ + 'li', + false + ] + ], + [ + 'end', + [ + 'li', + false + ] + ], + [ + 'close', + ['li'] + ], + [ + 'start', + [ + 'li', + false + ] + ], + [ + 'end', + [ + 'li', + false + ] + ], + [ + 'close', + ['li'] + ], + [ + 'close', + ['ul'] + ], + [ + 'done', + [] + ] + ])); + }); + test('supports single character attributes (#1132)', function () { + parser('', makeChecks([ + [ + 'start', + [ + 'circle', + false + ] + ], + [ + 'attrStart', + ['r'] + ], + [ + 'attrValue', + ['25'] + ], + [ + 'attrEnd', + ['r'] + ], + [ + 'end', + [ + 'circle', + false + ] + ], + [ + 'close', + ['circle'] + ], + [ + 'done', + [] + ] + ])); + }); + test('accept custom tag with colon ":" #1108', function () { + parser('', makeChecks([ + [ + 'start', + [ + 'x:widget', + true + ] + ], + [ + 'end', + [ + 'x:widget', + true + ] + ], + [ + 'done', + [] + ] + ])); + }); + test('output json', function () { + var tests = [ + [ + 'start', + [ + 'h1', + false + ] + ], + [ + 'attrStart', + ['id'] + ], + [ + 'attrValue', + ['foo'] + ], + [ + 'attrEnd', + ['id'] + ], + [ + 'special', + ['#if'] + ], + [ + 'special', + ['.'] + ], + [ + 'special', + ['/if'] + ], + [ + 'attrStart', + ['class'] + ], + [ + 'attrValue', + ['a'] + ], + [ + 'special', + ['foo'] + ], + [ + 'attrEnd', + ['class'] + ], + [ + 'end', + [ + 'h1', + false + ] + ], + [ + 'chars', + ['Hello '] + ], + [ + 'special', + ['message'] + ], + [ + 'chars', + ['!'] + ], + [ + 'close', + ['h1'] + ], + [ + 'done', + [] + ] + ]; + var intermediate = parser('

      Hello {{message}}!

      ', makeChecks(tests), true); + parser(intermediate, makeChecks(tests)); + }); + test('less than outside of an element', function () { + var tests = [ + [ + 'start', + [ + 'h1', + false + ] + ], + [ + 'end', + [ + 'h1', + false + ] + ], + [ + 'chars', + [' < '] + ], + [ + 'close', + ['h1'] + ], + [ + 'done', + [] + ] + ]; + var intermediate = parser('

      <

      ', makeChecks(tests), true); + parser(intermediate, makeChecks(tests)); + }); + test('allow () and [] to enclose attributes', function () { + parser('

      ', makeChecks([ + [ + 'start', + [ + 'p', + false + ] + ], + [ + 'attrStart', + ['[click]'] + ], + [ + 'attrValue', + ['test'] + ], + [ + 'attrEnd', + ['[click]'] + ], + [ + 'end', + ['p'] + ], + [ + 'close', + ['p'] + ], + [ + 'done', + [] + ] + ])); + parser('

      ', makeChecks([ + [ + 'start', + [ + 'p', + false + ] + ], + [ + 'attrStart', + [encoder.encode('(click)')] + ], + [ + 'attrValue', + ['test'] + ], + [ + 'attrEnd', + [encoder.encode('(click)')] + ], + [ + 'end', + ['p'] + ], + [ + 'close', + ['p'] + ], + [ + 'done', + [] + ] + ])); + parser('

      ', makeChecks([ + [ + 'start', + [ + 'p', + false + ] + ], + [ + 'attrStart', + [encoder.encode('(click-me)')] + ], + [ + 'attrValue', + ['test'] + ], + [ + 'attrEnd', + [encoder.encode('(click-me)')] + ], + [ + 'end', + ['p'] + ], + [ + 'close', + ['p'] + ], + [ + 'done', + [] + ] + ])); + parser('

      ', makeChecks([ + [ + 'start', + [ + 'p', + false + ] + ], + [ + 'attrStart', + [encoder.encode('(click_me)')] + ], + [ + 'attrValue', + ['test'] + ], + [ + 'attrEnd', + [encoder.encode('(click_me)')] + ], + [ + 'end', + ['p'] + ], + [ + 'close', + ['p'] + ], + [ + 'done', + [] + ] + ])); + }); + test('allow {} to enclose attributes', function () { + parser.parseAttrs('{a}="b" {{#c}}d{{/c}}', makeChecks([ + [ + 'attrStart', + [encoder.encode('{a}')] + ], + [ + 'attrValue', + ['b'] + ], + [ + 'attrEnd', + [encoder.encode('{a}')] + ], + [ + 'special', + ['#c'] + ], + [ + 'attrStart', + ['d'] + ], + [ + 'attrEnd', + ['d'] + ], + [ + 'special', + ['/c'] + ] + ])); + }); + test('tripple curly in attrs', function () { + parser.parseAttrs('items="{{{ completed }}}"', makeChecks([ + [ + 'attrStart', + ['items'] + ], + [ + 'special', + ['{ completed '] + ], + [ + 'attrEnd', + ['items'] + ] + ])); + }); + test('something', function () { + parser.parseAttrs('c d=\'e\'', makeChecks([ + [ + 'attrStart', + ['c'] + ], + [ + 'attrEnd', + ['c'] + ], + [ + 'attrStart', + ['d'] + ], + [ + 'attrValue', + ['e'] + ], + [ + 'attrEnd', + ['d'] + ] + ])); + }); + test('references', function () { + parser('', makeChecks([ + [ + 'start', + [ + 'year-selector', + true + ] + ], + [ + 'attrStart', + ['*y'] + ], + [ + 'attrEnd', + ['*y'] + ], + [ + 'end', + ['year-selector'] + ], + [ + 'done', + [] + ] + ])); + }); + test('quotes around attributes and other lazy attribute writing (#2097)', function () { + parser('', makeChecks([ + [ + 'start', + [ + 'c-d', + true + ] + ], + [ + 'attrStart', + ['a'] + ], + [ + 'attrValue', + ['{z}'] + ], + [ + 'attrEnd', + ['a'] + ], + [ + 'end', + ['c-d'] + ], + [ + 'done', + [] + ] + ])); + parser('', makeChecks([ + [ + 'start', + [ + 'span', + true + ] + ], + [ + 'attrStart', + ['v'] + ], + [ + 'special', + ['.'] + ], + [ + 'attrEnd', + ['v'] + ], + [ + 'end', + ['span'] + ], + [ + 'done', + [] + ] + ])); + parser('
      ', makeChecks([ + [ + 'start', + [ + 'div', + true + ] + ], + [ + 'special', + ['^f'] + ], + [ + 'attrStart', + ['d'] + ], + [ + 'attrEnd', + ['d'] + ], + [ + 'special', + ['/f'] + ], + [ + 'end', + ['div'] + ], + [ + 'done', + [] + ] + ])); + }); + test('camelCased attributes are converted to spinal-case', function () { + parser.parseAttrs('({camelCase})=\'assigned\'', makeChecks([ + [ + 'attrStart', + [encoder.encode('({camelCase})')] + ], + [ + 'attrValue', + ['assigned'] + ], + [ + 'attrEnd', + [encoder.encode('({camelCase})')] + ] + ])); + }); + test('elements that have attributes with equal signs and no values are handled appropriately (#17)', function () { + parser('', makeChecks([ + [ + 'start', + [ + 'input', + true + ] + ], + [ + 'attrStart', + ['class'] + ], + [ + 'attrValue', + ['toggle'] + ], + [ + 'attrEnd', + ['class'] + ], + [ + 'attrStart', + ['type'] + ], + [ + 'attrValue', + ['checkbox'] + ], + [ + 'attrEnd', + ['type'] + ], + [ + 'attrStart', + [encoder.encode('{($checked)}')] + ], + [ + 'attrValue', + ['complete'] + ], + [ + 'attrEnd', + [encoder.encode('{($checked)}')] + ], + [ + 'attrStart', + [encoder.encode('($change)')] + ], + [ + 'attrEnd', + [encoder.encode('($change)')] + ], + [ + 'end', + ['input'] + ], + [ + 'done', + [] + ] + ])); + }); + test('{{}} in attribute values are handled correctly (#34)', function () { + var tests = [ + [ + 'start', + [ + 'h1', + false + ] + ], + [ + 'attrStart', + ['class'] + ], + [ + 'special', + ['foo'] + ], + [ + 'attrValue', + ['a'] + ], + [ + 'attrEnd', + ['class'] + ], + [ + 'end', + [ + 'h1', + false + ] + ], + [ + 'close', + ['h1'] + ], + [ + 'done', + [] + ] + ]; + parser('

      ', makeChecks(tests)); + }); + test('> in attribute values are handled correctly', function () { + parser('

      bar

      ', makeChecks([ + [ + 'start', + [ + 'h1', + false + ] + ], + [ + 'attrStart', + ['data-content'] + ], + [ + 'attrValue', + ['foo'] + ], + [ + 'attrEnd', + ['data-content'] + ], + [ + 'end', + [ + 'h1', + false + ] + ], + [ + 'chars', + ['bar'] + ], + [ + 'close', + ['h1'] + ], + [ + 'done', + [] + ] + ])); + parser('

      bar

      ', makeChecks([ + [ + 'start', + [ + 'h1', + false + ] + ], + [ + 'attrStart', + ['data-nothing'] + ], + [ + 'attrEnd', + ['data-nothing'] + ], + [ + 'attrStart', + ['data-something'] + ], + [ + 'attrValue', + ['something'] + ], + [ + 'attrEnd', + ['data-something'] + ], + [ + 'attrStart', + ['data-content'] + ], + [ + 'attrValue', + ['foo'] + ], + [ + 'attrEnd', + ['data-content'] + ], + [ + 'attrStart', + ['data-something-after'] + ], + [ + 'attrValue', + ['something-after'] + ], + [ + 'attrEnd', + ['data-something-after'] + ], + [ + 'end', + [ + 'h1', + false + ] + ], + [ + 'chars', + ['bar'] + ], + [ + 'close', + ['h1'] + ], + [ + 'done', + [] + ] + ])); + parser('

      \nbar

      ', makeChecks([ + [ + 'start', + [ + 'h1', + false + ] + ], + [ + 'attrStart', + ['data-first'] + ], + [ + 'attrValue', + ['foo'] + ], + [ + 'attrEnd', + ['data-first'] + ], + [ + 'attrStart', + ['data-second'] + ], + [ + 'attrValue', + ['><>>>>>>>/>> \n />'] + ], + [ + 'attrEnd', + ['data-second'] + ], + [ + 'end', + [ + 'h1', + false + ] + ], + [ + 'chars', + ['\nbar'] + ], + [ + 'close', + ['h1'] + ], + [ + 'done', + [] + ] + ])); + }); + test('tags with data attributes are allowed in comments (#2)', function () { + parser('{{! foo }}', makeChecks([ + [ + 'special', + ['! foo '] + ], + [ + 'done', + [] + ] + ])); + parser('{{! }}', makeChecks([ + [ + 'special', + ['! '] + ], + [ + 'done', + [] + ] + ])); + parser('{{! }}', makeChecks([ + [ + 'special', + ['! '] + ], + [ + 'done', + [] + ] + ])); + }); + test('multiline special comments (#14)', function () { + parser('{{! foo !}}', makeChecks([ + [ + 'special', + ['! foo !'] + ], + [ + 'done', + [] + ] + ])); + parser('{{! {{foo}} {{bar}} !}}', makeChecks([ + [ + 'special', + ['! {{foo}} {{bar}} !'] + ], + [ + 'done', + [] + ] + ])); + parser('{{!\n{{foo}}\n{{bar}}\n!}}', makeChecks([ + [ + 'special', + ['!\n{{foo}}\n{{bar}}\n!'] + ], + [ + 'done', + [] + ] + ])); + }); + test('spaces in attribute names that start with `{` or `(` are encoded (#48)', function () { + var tests = [ + [ + 'start', + [ + 'h1', + false + ] + ], + [ + 'attrStart', + [encoder.encode('{foo bar}')] + ], + [ + 'attrValue', + ['a'] + ], + [ + 'attrEnd', + [encoder.encode('{foo bar}')] + ], + [ + 'end', + [ + 'h1', + false + ] + ], + [ + 'close', + ['h1'] + ], + [ + 'done', + [] + ] + ]; + parser('

      ', makeChecks(tests)); + }); + test('for attributes without values, spaces in attribute names that start with `{` or `(` are encoded (#48)', function () { + var tests = [ + [ + 'start', + [ + 'h1', + false + ] + ], + [ + 'attrStart', + [encoder.encode('{foo }')] + ], + [ + 'attrEnd', + [encoder.encode('{foo }')] + ], + [ + 'attrStart', + [encoder.encode('{bar }')] + ], + [ + 'attrEnd', + [encoder.encode('{bar }')] + ], + [ + 'end', + [ + 'h1', + false + ] + ], + [ + 'close', + ['h1'] + ], + [ + 'done', + [] + ] + ]; + parser('

      ', makeChecks(tests)); + }); + test('mismatched brackets work: {(foo})', function () { + var tests = [ + [ + 'start', + [ + 'h1', + false + ] + ], + [ + 'attrStart', + [encoder.encode('{(foo})')] + ], + [ + 'attrValue', + ['a'] + ], + [ + 'attrEnd', + [encoder.encode('{(foo})')] + ], + [ + 'end', + [ + 'h1', + false + ] + ], + [ + 'close', + ['h1'] + ], + [ + 'done', + [] + ] + ]; + parser('

      ', makeChecks(tests)); + }); + test('mismatched brackets work: ({foo)}', function () { + var tests = [ + [ + 'start', + [ + 'h1', + false + ] + ], + [ + 'attrStart', + [encoder.encode('({foo)}')] + ], + [ + 'attrValue', + ['a'] + ], + [ + 'attrEnd', + [encoder.encode('({foo)}')] + ], + [ + 'end', + [ + 'h1', + false + ] + ], + [ + 'close', + ['h1'] + ], + [ + 'done', + [] + ] + ]; + parser('

      ', makeChecks(tests)); + }); + test('forward slashes are encoded (#52)', function () { + var tests = [ + [ + 'start', + [ + 'h1', + false + ] + ], + [ + 'attrStart', + [encoder.encode('{foo/bar}')] + ], + [ + 'attrValue', + ['a'] + ], + [ + 'attrEnd', + [encoder.encode('{foo/bar}')] + ], + [ + 'end', + [ + 'h1', + false + ] + ], + [ + 'close', + ['h1'] + ], + [ + 'done', + [] + ] + ]; + parser('

      ', makeChecks(tests)); + }); + test('camelCase properties are encoded with on:, :to, :from, :bind bindings', function () { + var tests = [ + [ + 'start', + [ + 'h1', + false + ] + ], + [ + 'attrStart', + [encoder.encode('on:aB')] + ], + [ + 'attrValue', + ['c'] + ], + [ + 'attrEnd', + [encoder.encode('on:aB')] + ], + [ + 'attrStart', + [encoder.encode('dE:to')] + ], + [ + 'attrValue', + ['f'] + ], + [ + 'attrEnd', + [encoder.encode('dE:to')] + ], + [ + 'attrStart', + [encoder.encode('gH:from')] + ], + [ + 'attrValue', + ['i'] + ], + [ + 'attrEnd', + [encoder.encode('gH:from')] + ], + [ + 'attrStart', + [encoder.encode('jK:bind')] + ], + [ + 'attrValue', + ['l'] + ], + [ + 'attrEnd', + [encoder.encode('jK:bind')] + ], + [ + 'end', + [ + 'h1', + false + ] + ], + [ + 'close', + ['h1'] + ], + [ + 'done', + [] + ] + ]; + parser('

      ', makeChecks(tests)); + }); + testHelpers.dev.devOnlyTest('Warn on missing attribute value end quotes (canjs/can-view-parser#7)', function () { + var makeWarnChecks = function (input, texts) { + var count = 0; + var teardown = testHelpers.dev.willWarn(/End quote is missing for/, function (message, matched) { + ok(matched, texts[count++]); + }); + parser(input, { + start: function (tagName, unary) { + }, + end: function (tagName, unary) { + }, + attrStart: function (attrName) { + }, + attrEnd: function (attrName) { + }, + attrValue: function (val) { + }, + done: function () { + } + }); + equal(count, teardown()); + }; + makeWarnChecks('', ['1: End quote is missing for callback']); + makeWarnChecks('', ['1: End quote is missing for current-page']); + makeWarnChecks('
      ', ['1: End quote is missing for current-page']); + makeWarnChecks('', ['1: End quote is missing for current-page']); + }); + test('TextNodes are not inserted before the or after the ', function () { + var tests = [ + [ + 'start', + [ + 'html', + false + ] + ], + [ + 'end', + [ + 'html', + false + ] + ], + [ + 'start', + [ + 'head', + false + ] + ], + [ + 'end', + [ + 'head', + false + ] + ], + [ + 'chars', + ['\n\t\t'] + ], + [ + 'start', + [ + 'title', + false + ] + ], + [ + 'end', + [ + 'title', + false + ] + ], + [ + 'chars', + ['Test'] + ], + [ + 'close', + ['title'] + ], + [ + 'chars', + ['\n\t\t'] + ], + [ + 'close', + ['head'] + ], + [ + 'chars', + ['\n\t'] + ], + [ + 'start', + [ + 'body', + false + ] + ], + [ + 'end', + [ + 'body', + false + ] + ], + [ + 'chars', + ['\n\t\t'] + ], + [ + 'start', + [ + 'h1', + false + ] + ], + [ + 'end', + [ + 'h1', + false + ] + ], + [ + 'chars', + ['Test'] + ], + [ + 'close', + ['h1'] + ], + [ + 'chars', + ['\n\t'] + ], + [ + 'close', + ['body'] + ], + [ + 'close', + ['html'] + ], + [ + 'done', + [] + ] + ]; + var html = '\n\t\n\t\tTest\n\t\t\n\t\n\t\t

      Test

      \n\t\n'; + parser(html, makeChecks(tests)); + }); +}); +/*can-view-scope@4.11.1#test/variable-scope-test*/ +define('can-view-scope@4.11.1#test/variable-scope-test', [ + 'require', + 'exports', + 'module', + 'can-view-scope', + 'steal-qunit', + 'can-simple-map', + 'can-reflect' +], function (require, exports, module) { + var Scope = require('can-view-scope'); + var QUnit = require('steal-qunit'); + var SimpleMap = require('can-simple-map'); + var canReflect = require('can-reflect'); + QUnit.module('can-view-scope variable scope'); + QUnit.test('reading', function () { + var root = { + rootProp: 'ROOT', + conflictProp: 'ROOT' + }; + var scope = new Scope(root).add({ + variableProp: 'VARIABLE', + conflictProp: 'VARIABLE' + }, { variable: true }); + QUnit.equal(scope.get('variableProp'), 'VARIABLE', 'can read a variable'); + QUnit.equal(scope.get('this.rootProp'), 'ROOT', 'can pass variables for the root'); + QUnit.equal(scope.get('this.conflictProp'), 'ROOT', 'this.conflictProp'); + QUnit.equal(scope.get('./conflictProp'), 'ROOT', './conflictProp'); + QUnit.equal(scope.get('conflictProp'), 'VARIABLE', 'conflictProp'); + QUnit.equal(scope.get('this'), root, 'this is right'); + var root2 = { + root2Prop: 'ROOT2', + conflictProp: 'ROOT2' + }; + var scope2 = new Scope(root).add(root2).add({ + variableProp: 'VARIABLE', + conflictProp: 'VARIABLE' + }, { variable: true }); + QUnit.equal(scope2.get('variableProp'), 'VARIABLE', 'can read a variable'); + QUnit.equal(scope2.get('this.root2Prop'), 'ROOT2', 'can pass variables for the root 2'); + QUnit.equal(scope2.get('this.conflictProp'), 'ROOT2', 'this.conflictProp'); + QUnit.equal(scope2.get('./conflictProp'), 'ROOT2', './conflictProp'); + QUnit.equal(scope2.get('conflictProp'), 'VARIABLE', 'conflictProp'); + QUnit.equal(scope2.get('../conflictProp'), 'ROOT', '../conflictProp'); + var root3 = { + root3Prop: 'ROOT3', + conflictProp: 'ROOT3' + }; + var scope3 = new Scope(root).add(root2).add(root3).add({ + variableProp: 'VARIABLE', + conflictProp: 'VARIABLE' + }, { variable: true }); + QUnit.equal(scope3.get('../../conflictProp'), 'ROOT', '../../conflictProp'); + }); + QUnit.test('writing', function () { + var root = new SimpleMap({ name: 'ROOT' }); + var scope; + scope = new Scope(root).addLetContext(); + scope.set('rootProp', 'VALUE'); + QUnit.equal(root.get('rootProp'), 'VALUE', 'wrote to property with .set'); + var rootProp = scope.computeData('rootProp2'); + canReflect.setValue(rootProp, 'VALUE2'); + QUnit.equal(root.get('rootProp2'), 'VALUE2', 'wrote property by setting ScopeKeyData'); + var rootProp3 = scope.computeData('rootProp3'); + canReflect.onValue(rootProp3, function () { + }); + canReflect.setValue(rootProp3, 'VALUE3'); + QUnit.equal(root.get('rootProp3'), 'VALUE3', 'wrote to property by setting bound ScopeKeyData'); + scope = new Scope(root).addLetContext({ tempProp: undefined }); + scope.set('tempProp', 'foo'); + QUnit.equal(root.get('tempProp'), undefined, 'write to undefined not set on root'); + QUnit.equal(scope.get('tempProp'), 'foo', 'able to read from root'); + }); +}); +/*can-view-scope@4.11.1#test/scope-set-test*/ +define('can-view-scope@4.11.1#test/scope-set-test', [ + 'require', + 'exports', + 'module', + 'can-view-scope', + 'steal-qunit', + 'can-test-helpers', + 'can-simple-map', + 'can-simple-observable' +], function (require, exports, module) { + var Scope = require('can-view-scope'); + var QUnit = require('steal-qunit'); + var testHelpers = require('can-test-helpers'); + var SimpleMap = require('can-simple-map'); + var SimpleObservable = require('can-simple-observable'); + QUnit.module('can-view-scope set'); + QUnit.test('computes are set as this and . and ../', function () { + var value = new SimpleObservable(1); + var scope = new Scope(value); + scope.set('this', 2); + QUnit.equal(scope.get('this'), 2, 'this read value'); + scope.set('.', 3); + QUnit.equal(scope.get('this'), 3, '. read value'); + scope = scope.add({}); + scope.set('..', 4); + QUnit.equal(scope.get('..'), 4, '.. read value'); + }); + QUnit.test('can set scope attributes with ../ (#2132)', function () { + var map = new SimpleMap(); + var scope = new Scope(map); + var top = scope.add(new SimpleMap()); + top.set('../foo', 'bar'); + equal(map.attr('foo'), 'bar'); + }); + QUnit.test('Scope attributes can be set (#1297, #1304)', function () { + var comp = new SimpleObservable('Test'); + var map = new SimpleMap({ other: new SimpleMap({ name: 'Justin' }) }); + var scope = new Scope({ + name: 'Matthew', + other: { + person: { name: 'David' }, + comp: comp + } + }); + scope.set('name', 'Wilbur'); + equal(scope.get('name'), 'Wilbur', 'set(key) updated'); + scope.set('other.person.name', 'Dave'); + equal(scope.get('other.person.name'), 'Dave', 'set(key.key.key) updated'); + scope.set('other.comp', 'Changed'); + equal(comp.get(), 'Changed', 'set(key.compute) updated'); + scope = new Scope(map); + scope.set('other.name', 'Brian'); + equal(scope.get('other.name'), 'Brian', 'Value updated'); + equal(map.attr('other').attr('name'), 'Brian', 'Name update in map'); + }); + QUnit.test('setting a key on a non observable context', function () { + var context = { colors: new SimpleMap() }; + var scope = new Scope(context); + scope.set('colors', { prop: 'bar' }); + QUnit.deepEqual(context.colors.attr(), { prop: 'bar' }, 'can updateDeep'); + }); + QUnit.test('filename and lineNumber can be read from anywhere in scope chain', function () { + var parent = new Scope({}); + var scope = parent.add({}); + parent.set('scope.filename', 'my-cool-file.txt'); + parent.set('scope.lineNumber', '5'); + QUnit.equal(scope.peek('scope.filename'), 'my-cool-file.txt', 'scope.peek("scope.filename")'); + QUnit.equal(scope.peek('scope.lineNumber'), '5', 'scope.peek("scope.lineNumber")'); + }); + testHelpers.dev.devOnlyTest('Setting a value to an attribute with an undefined parent errors (canjs/can-stache-bindings#298)', function () { + var teardown = testHelpers.dev.willError(/Attempting to set a value at (.+) where (.+) is undefined./); + var scope = new Scope({}); + scope.set('../person.name', 'Christopher'); + QUnit.equal(teardown(), 1, 'saw errors'); + }); +}); +/*can-view-scope@4.11.1#test/scope-key-data-test*/ +define('can-view-scope@4.11.1#test/scope-key-data-test', [ + 'require', + 'exports', + 'module', + 'can-view-scope', + 'can-simple-map', + 'steal-qunit', + 'can-reflect', + 'can-simple-observable', + 'can-observation' +], function (require, exports, module) { + var Scope = require('can-view-scope'); + var SimpleMap = require('can-simple-map'); + var QUnit = require('steal-qunit'); + var canReflect = require('can-reflect'); + var SimpleObservable = require('can-simple-observable'); + var Observation = require('can-observation'); + QUnit.module('can-view-scope scope-key-data'); + QUnit.test('able to scope-key-data this', function () { + var value = new SimpleObservable(1); + var scope = new Scope(value); + var thisObservable = scope.computeData('this'); + thisObservable.on(function () { + }); + QUnit.equal(canReflect.getValue(thisObservable), 1); + canReflect.setValue(thisObservable, 2); + }); + QUnit.test('ScopeKeyData\'s thisArg is observable', function () { + var doSomething = function () { + return this.value; + }; + var context = new SimpleMap({ + foo: { + doSomething: doSomething, + value: 'A' + } + }); + var res = new Scope(context).computeData('this.foo@doSomething', { proxyMethods: false }); + var obs = new Observation(function () { + var func = canReflect.getValue(res); + return func.call(res.thisArg); + }); + canReflect.onValue(obs, function (value) { + QUnit.equal(value, 'B'); + }); + context.set('foo', { + doSomething: doSomething, + value: 'B' + }); + }); + QUnit.test('reading ScopeKeyData will update underlying observable', function () { + var context = new SimpleMap({ 'prop': 'value' }); + var prop = new Scope(context).computeData('this.prop', { proxyMethods: false }); + canReflect.onValue(prop, function () { + }); + context.on('prop', function () { + QUnit.equal(canReflect.getValue(prop), 'VALUE', 'able to read fastPath value'); + }, 'notify'); + context.set('prop', 'VALUE'); + var root = new SimpleObservable('value'); + var observation = new Observation(function () { + return root.value; + }); + context = { 'prop': observation }; + prop = new Scope(context).computeData('this.prop', { proxyMethods: false }); + canReflect.onValue(prop, function () { + }); + canReflect.onValue(root, function () { + QUnit.equal(canReflect.getValue(prop), 'VALUE', 'able to read deep, non-fast-path value'); + }, 'notify'); + root.value = 'VALUE'; + }); +}); +/*can-view-scope@4.11.1#test/scope-test*/ +define('can-view-scope@4.11.1#test/scope-test', [ + 'require', + 'exports', + 'module', + 'can-view-scope', + 'can-stache-key', + '../template-context', + 'can-symbol', + 'steal-qunit', + 'can-reflect', + 'can-observation', + 'can-test-helpers', + 'can-simple-map', + 'can-simple-observable', + 'can-observation-recorder', + 'can-reflect-dependencies', + 'can-stache-helpers', + './variable-scope-test', + './scope-set-test', + './scope-key-data-test' +], function (require, exports, module) { + (function (global, require, exports, module) { + var Scope = require('can-view-scope'); + var observeReader = require('can-stache-key'); + var TemplateContext = require('../template-context'); + var canSymbol = require('can-symbol'); + var QUnit = require('steal-qunit'); + var canReflect = require('can-reflect'); + var Observation = require('can-observation'); + var testHelpers = require('can-test-helpers'); + var SimpleMap = require('can-simple-map'); + var SimpleObservable = require('can-simple-observable'); + var ObservationRecorder = require('can-observation-recorder'); + var canReflectDeps = require('can-reflect-dependencies'); + var canStacheHelpers = require('can-stache-helpers'); + QUnit.module('can/view/scope'); + test('basics', function () { + var address = new SimpleMap({ zip: 60647 }); + var person = new SimpleMap({ + name: 'Justin', + address: address + }); + var items = new SimpleMap({ + people: person, + count: 1000 + }); + var itemsScope = new Scope(items), personScope = new Scope(person, itemsScope), zipScope = new Scope(address, personScope); + var nameInfo; + var c = new Observation(function () { + nameInfo = zipScope.read('../name'); + }); + canReflect.onValue(c, function () { + }); + deepEqual(nameInfo.reads, [{ + key: 'name', + at: false + }], 'reads'); + equal(nameInfo.scope, personScope, 'scope'); + equal(nameInfo.value, 'Justin', 'value'); + equal(nameInfo.rootObserve, person, 'rootObserve'); + }); + test('Scope.prototype.computeData', function () { + var map = new SimpleMap(); + var base = new Scope(map); + var computeData = base.computeData('age'); + equal(computeData.observation, computeData.options.observation, 'ScopeKeyData should have a backing observation stored on its `options`'); + var age = computeData.compute; + equal(age(), undefined, 'age is not set'); + age.bind('change', function (ev, newVal, oldVal) { + equal(newVal, 31, 'newVal is provided correctly'); + equal(oldVal, undefined, 'oldVal is undefined'); + }); + age(31); + equal(map.attr('age'), 31, 'maps age is set correctly'); + }); + test('backtrack path (#163)', function () { + var row = new SimpleMap({ first: 'Justin' }), col = { format: 'str' }, base = new Scope(row), cur = base.add(col); + equal(cur.peek('.'), col, 'got col'); + equal(cur.peek('..'), row, 'got row'); + equal(cur.peek('../first'), 'Justin', 'got row'); + }); + test('nested properties with compute', function () { + var me = new SimpleMap({ name: new SimpleMap({ first: 'Justin' }) }); + var cur = new Scope(me); + var compute = cur.computeData('name.first').compute; + var changes = 0; + var handler = function (ev, newVal, oldVal) { + if (changes === 0) { + equal(oldVal, 'Justin'); + equal(newVal, 'Brian'); + } else if (changes === 1) { + equal(oldVal, 'Brian'); + equal(newVal, undefined); + } else if (changes === 2) { + equal(oldVal, undefined); + equal(newVal, 'Payal'); + } else if (changes === 3) { + equal(oldVal, 'Payal'); + equal(newVal, 'Curtis'); + } + changes++; + }; + compute.bind('change', handler); + equal(compute(), 'Justin', 'read value after bind'); + me.attr('name').attr('first', 'Brian'); + me.attr('name', undefined); + me.attr('name', { first: 'Payal' }); + me.attr('name', new SimpleMap({ first: 'Curtis' })); + compute.unbind('change', handler); + }); + test('function at the end', function () { + var compute = new Scope({ + me: { + info: function () { + return 'Justin'; + } + } + }).computeData('me.info').compute; + equal(compute()(), 'Justin'); + var fn = function () { + return this.name; + }; + var compute2 = new Scope({ + me: { + info: fn, + name: 'Hank' + } + }).computeData('me.info', { + isArgument: true, + args: [] + }).compute; + equal(compute2()(), 'Hank'); + }); + test('binds to the right scope only', function () { + var baseMap = new SimpleMap({ me: new SimpleMap({ name: new SimpleMap({ first: 'Justin' }) }) }); + var base = new Scope(baseMap); + var topMap = new SimpleMap({ me: new SimpleMap({ name: new SimpleMap({}) }) }); + var scope = base.add(topMap); + var compute = scope.computeData('../me.name.first').compute; + compute.bind('change', function (ev, newVal, oldVal) { + equal(oldVal, 'Justin'); + equal(newVal, 'Brian'); + }); + equal(compute(), 'Justin'); + topMap.attr('me').attr('name').attr('first', 'Payal'); + baseMap.attr('me').attr('name').attr('first', 'Brian'); + }); + test('Scope read returnObserveMethods=true', function () { + var MapConstruct = SimpleMap.extend({ + foo: function (arg) { + equal(this, data.map, 'correct this'); + equal(arg, true, 'correct arg'); + } + }); + var data = { map: new MapConstruct() }; + var res = Scope.read(data, observeReader.reads('map.foo'), { isArgument: true }); + res.value(true); + }); + test('rooted observable is able to update correctly', function () { + var baseMap = new SimpleMap({ name: new SimpleMap({ first: 'Justin' }) }); + var scope = new Scope(baseMap); + var compute = scope.computeData('name.first').compute; + equal(compute(), 'Justin'); + baseMap.attr('name', new SimpleMap({ first: 'Brian' })); + equal(compute(), 'Brian'); + }); + test('computeData reading an object with a compute', function () { + var age = new SimpleObservable(21); + var scope = new Scope({ person: { age: age } }); + var computeData = scope.computeData('person.age'); + var value = computeData.compute(); + equal(value, 21, 'correct value'); + computeData.compute(31); + equal(age.get(), 31, 'age updated'); + }); + test('computeData with initial empty compute (#638)', function () { + expect(2); + var c = new SimpleObservable(); + var scope = new Scope({ compute: c }); + var computeData = scope.computeData('compute'); + equal(computeData.compute(), undefined); + computeData.compute.bind('change', function (ev, newVal) { + equal(newVal, 'compute value'); + }); + c.set('compute value'); + }); + test('Can read static properties on constructors (#634)', function () { + var Foo = SimpleMap.extend({ static_prop: 'baz' }, { proto_prop: 'thud' }); + var data = new Foo({ own_prop: 'quux' }), scope = new Scope(data); + equal(scope.computeData('constructor.static_prop').compute(), 'baz', 'static prop'); + }); + test('Can read static properties on constructors (#634)', function () { + var Foo = SimpleMap.extend({ static_prop: 'baz' }, { proto_prop: 'thud' }); + var data = new Foo({ own_prop: 'quux' }), scope = new Scope(data); + equal(scope.computeData('constructor.static_prop').compute(), 'baz', 'static prop'); + }); + test('Scope lookup restricted to current scope with ./ (#874)', function () { + var current; + var scope = new Scope(new SimpleMap({ value: 'A Value' })).add(current = new SimpleMap({})); + var compute = scope.computeData('./value').compute; + equal(compute(), undefined, 'no initial value'); + compute.bind('change', function (ev, newVal) { + equal(newVal, 'B Value', 'changed'); + }); + compute('B Value'); + equal(current.attr('value'), 'B Value', 'updated'); + }); + test('reading properties on undefined (#1314)', function () { + var scope = new Scope(undefined); + var compute = scope.compute('property'); + equal(compute(), undefined, 'got back undefined'); + }); + test('computeData.compute get/sets computes in maps', function () { + var cmpt = new SimpleObservable(4); + var map = new SimpleMap(); + map.attr('computer', cmpt); + var scope = new Scope(map); + var computeData = scope.computeData('computer', {}); + equal(computeData.compute(), 4, 'got the value'); + computeData.compute(5); + equal(cmpt.get(), 5, 'updated compute value'); + equal(computeData.compute(), 5, 'the compute has the right value'); + }); + test('computesData can find update when initially undefined parent scope becomes defined (#579)', function () { + expect(2); + var map = new SimpleMap(); + var scope = new Scope(map); + var top = scope.add(new SimpleMap()); + var computeData = top.computeData('../value', {}); + equal(computeData.compute(), undefined, 'initially undefined'); + computeData.compute.bind('change', function (ev, newVal) { + equal(newVal, 'first'); + }); + map.attr('value', 'first'); + }); + test('can read parent context with ../ (#2244)', function () { + var map = new SimpleMap(); + var scope = new Scope(map); + var top = scope.add(new SimpleMap()); + equal(top.peek('../'), map, 'looked up value correctly'); + }); + test('trying to read constructor from refs scope is ok', function () { + var map = new TemplateContext(); + var construct = new Observation(function () { + return map.constructor; + }); + canReflect.onValue(construct, function () { + }); + equal(canReflect.getValue(construct), TemplateContext); + }); + test('reading from a string in a nested scope doesn\'t throw an error (#22)', function () { + var foo = new SimpleObservable('foo'); + var bar = new SimpleObservable('bar'); + var scope = new Scope(foo); + var localScope = scope.add(bar); + equal(localScope.read('foo').value, undefined); + }); + test('Optimize for compute().observableProperty (#29)', function () { + var map = new SimpleMap({ value: 'a' }); + var wrap = new SimpleObservable(map); + var scope = new Scope(wrap); + var scopeKeyData = scope.computeData('value'); + var scopeCompute = scopeKeyData.compute; + var changeNumber = 0; + scopeCompute.on('change', function (ev, newVal, oldVal) { + if (changeNumber === 1) { + QUnit.equal(newVal, 'b'); + QUnit.equal(oldVal, 'a'); + QUnit.ok(scopeKeyData.fastPath, 'still fast path'); + changeNumber++; + wrap.set(new SimpleMap({ value: 'c' })); + } else if (changeNumber === 2) { + QUnit.equal(newVal, 'c', 'got new value'); + QUnit.equal(oldVal, 'b', 'got old value'); + QUnit.notOk(scopeKeyData.fastPath, 'still fast path'); + } + }); + QUnit.ok(scopeKeyData.fastPath, 'fast path'); + changeNumber++; + map.attr('value', 'b'); + }); + test('a compute can observe the ScopeKeyData', 3, function () { + var map = new SimpleMap({ + value: 'a', + other: 'b' + }); + var wrap = new SimpleObservable(map); + var scope = new Scope(wrap); + var scopeKeyData = scope.computeData('value'); + var oldOnValue = scopeKeyData[canSymbol.for('can.onValue')]; + scopeKeyData[canSymbol.for('can.onValue')] = function () { + QUnit.ok(true, 'bound on the scopeKeyData'); + return oldOnValue.apply(this, arguments); + }; + var c = new Observation(function () { + return scopeKeyData.get() + map.attr('other'); + }); + canReflect.onValue(c, function (newValue) { + QUnit.equal(newValue, 'Ab', 'observation changed'); + }); + map.attr('value', 'A'); + }); + QUnit.asyncTest('unbinding clears all event bindings', function () { + var map = new SimpleMap({ + value: 'a', + other: 'b' + }); + var wrap = new SimpleObservable(map); + var scope = new Scope(wrap); + var scopeKeyData = scope.computeData('value'); + var c = new Observation(function () { + return scopeKeyData.get() + map.attr('other'); + }); + var handlers = function (newValue) { + QUnit.equal(newValue, 'Ab'); + }; + canReflect.onValue(c, handlers); + canReflect.offValue(c, handlers); + setTimeout(function () { + var handlers = map[canSymbol.for('can.meta')].handlers.get([]); + equal(handlers.length, 0, 'there are no bindings'); + start(); + }, 30); + }); + QUnit.test('computes are read as this and . and ../', function () { + var value = new SimpleObservable(1); + var scope = new Scope(value); + QUnit.equal(scope.get('this'), 1, 'this read value'); + QUnit.equal(scope.get('.'), 1, '. read value'); + scope = scope.add({}); + QUnit.equal(scope.get('..'), 1, '.. read value'); + }); + QUnit.test('maps are set with this.foo and ./foo', function () { + var map = new SimpleObservable(new SimpleMap({ value: 1 })); + var scope = new Scope(map); + scope.set('this.value', 2); + QUnit.equal(scope.get('this.value'), 2, 'this read value'); + scope.set('./value', 3); + QUnit.equal(scope.get('./value'), 3, '. read value'); + }); + testHelpers.dev.devOnlyTest('computeData dependencies', function (assert) { + var map = new SimpleMap({ value: 'a' }); + var scope = new Scope(map); + var computeData = scope.computeData('value'); + var c = new Observation(function () { + return computeData.get(); + }); + canReflect.onValue(c, function () { + }); + var dependencies = canReflect.getValueDependencies(c); + assert.ok(dependencies.valueDependencies.has(computeData), 'compute has computeData'); + assert.equal(dependencies.valueDependencies.size, 1, 'compute only has computeData'); + var mapValueDependencies = canReflectDeps.getDependencyDataOf(map, 'value'); + assert.ok(mapValueDependencies.whatIChange.derive.valueDependencies.has(computeData.observation), 'map.value -> computeData internal observation'); + assert.ok(mapValueDependencies.whatChangesMe.mutate.valueDependencies.has(computeData), 'computeData -> map.value'); + var computeDataDependencies = canReflect.getValueDependencies(computeData); + assert.ok(computeDataDependencies.valueDependencies.has(computeData.observation), 'computeData internal observation -> computeData'); + }); + testHelpers.dev.devOnlyTest('computeData dependencies for nested properties', function (assert) { + var justin = new SimpleMap({ name: 'justin' }); + var matthew = new SimpleMap({ name: 'matthew' }); + var map = new SimpleMap({ person: justin }); + var scope = new Scope(map); + var computeData = scope.computeData('person.name'); + var obs = new Observation(function () { + return computeData.get(); + }); + canReflect.onValue(obs, function () { + }); + var observationDependencies = canReflect.getValueDependencies(obs); + assert.ok(observationDependencies.valueDependencies.has(computeData), 'compute has computeData'); + assert.equal(observationDependencies.valueDependencies.size, 1, 'compute only has computeData'); + var mapPersonDependencies = canReflectDeps.getDependencyDataOf(map, 'person'); + assert.ok(mapPersonDependencies.whatIChange.derive.valueDependencies.has(computeData.observation), 'map.person -> computeData internal observation'); + var justinNameDependencies = canReflectDeps.getDependencyDataOf(justin, 'name'); + assert.ok(justinNameDependencies.whatIChange.derive.valueDependencies.has(computeData.observation), 'person.name -> computeData internal observation'); + assert.ok(justinNameDependencies.whatChangesMe.mutate.valueDependencies.has(computeData), 'computeData -> person.name'); + var computeDataDependencies = canReflect.getValueDependencies(computeData); + assert.ok(computeDataDependencies.valueDependencies.has(computeData.observation), 'computeData internal observation -> computeData'); + map.set('person', matthew); + justinNameDependencies = canReflectDeps.getDependencyDataOf(justin, 'name'); + var matthewNameDependencies = canReflectDeps.getDependencyDataOf(matthew, 'name'); + assert.notOk(justinNameDependencies, 'old person.name dependencies are removed'); + assert.ok(matthewNameDependencies.whatIChange.derive.valueDependencies.has(computeData.observation), 'person.name -> computeData internal observation changed'); + assert.ok(matthewNameDependencies.whatChangesMe.mutate.valueDependencies.has(computeData), 'computeData -> person.name changed'); + }); + QUnit.test('scopeKeyData offValue resets dependencyChange/start', function () { + var map = new SimpleMap({ + value: 'a', + other: 'b' + }); + var wrap = new SimpleObservable(map); + var scope = new Scope(wrap); + var scopeKeyData = scope.computeData('value'); + var handler = function () { + }; + canReflect.onValue(scopeKeyData, handler); + canReflect.offValue(scopeKeyData, handler); + QUnit.equal(scopeKeyData.observation.dependencyChange, Observation.prototype.dependencyChange, 'dependencyChange should be restored'); + QUnit.equal(scopeKeyData.observation.start, Observation.prototype.start, 'start should be restored'); + }); + QUnit.test('Rendering a template with a custom scope (#55)', function () { + var scope = new Scope({}); + QUnit.equal(scope.get('name'), undefined, 'No name'); + scope.set('name', 'John'); + QUnit.equal(scope.get('name'), 'John', 'Got the name'); + scope = scope.add({ name: 'Justin' }); + QUnit.equal(scope.get('name'), 'Justin', 'Got the top scope name'); + }); + QUnit.test('./ scope lookup should read current scope', function () { + var parent = new SimpleMap(); + var map = new SimpleMap(); + var scope = new Scope(parent).add(map); + QUnit.equal(scope.get('./'), map); + }); + QUnit.test('getTemplateContext() gives a scope with the templateContext', function () { + var map = new SimpleMap(); + var scope = new Scope(map); + var templateContext = scope.getTemplateContext(); + QUnit.ok(templateContext instanceof Scope, 'templateContext is a Scope'); + QUnit.ok(templateContext._context instanceof TemplateContext, 'templateContext context is a TemplateContext object'); + }); + QUnit.test('scope can be used to read from the templateContext', function () { + var map = new SimpleMap(); + var scope = new Scope(map); + QUnit.deepEqual(scope.peek('scope'), scope, 'scope'); + scope.set('scope.vars.name', 'Kevin'); + QUnit.equal(scope.peek('scope.vars.name'), 'Kevin', 'scope.vars.name === Kevin'); + var ageFn = function () { + return '30'; + }; + scope.set('scope.vars.age', ageFn); + QUnit.equal(scope.peek('scope.vars.age')(), '30', 'scope.vars.age === 30'); + }); + QUnit.test('scope.index reads from special scopes', function () { + var originalIndexHelper = canStacheHelpers.index; + delete canStacheHelpers.index; + var map1 = new SimpleMap({ index: 1 }); + var map2 = new SimpleMap({ index: 3 }); + var scope = new Scope(map1); + QUnit.equal(scope.peek('scope.index'), undefined, 'scope.index returns undefined if no special context exists'); + scope = scope.add({ index: 2 }, { special: true }).add(map2).add({ index: 0 }, { special: true }); + QUnit.equal(scope.peek('scope.index'), 0, 'scope.index is read correctly'); + QUnit.equal(scope._parent.peek('scope.index'), 2, 'scope.index is only read from special contexts'); + canStacheHelpers.index = originalIndexHelper; + }); + QUnit.test('scope.index should not return a global helper', function () { + var mockGlobalHelper = function () { + QUnit.ok(false, 'global helper should not be called'); + }; + var originalIndexHelper = canStacheHelpers.index; + canStacheHelpers.index = mockGlobalHelper; + var scope = new Scope({}); + QUnit.equal(scope.peek('scope.index'), undefined, 'scope.index returns undefined if no special context exists'); + canStacheHelpers.index = originalIndexHelper; + }); + QUnit.test('scope.key reads from special scopes', function () { + var map1 = new SimpleMap({ key: 'one' }); + var map2 = new SimpleMap({ key: 3 }); + var scope = new Scope(map1).add({ key: 'two' }, { special: true }).add(map2).add({ key: 'four' }, { special: true }); + QUnit.equal(scope.peek('scope.key'), 'four', 'scope.key is read correctly'); + QUnit.equal(scope._parent.peek('scope.key'), 'two', 'scope.key is only read from special contexts'); + }); + QUnit.test('variables starting with \'scope\' should not be read from templateContext (#104)', function () { + var map = new SimpleMap({ scope1: 'this is scope1' }); + var scope = new Scope(map); + QUnit.deepEqual(scope.peek('scope1'), 'this is scope1', 'scope1'); + }); + QUnit.test('nested properties can be read from templateContext.vars', function () { + var foo = new SimpleMap({ bar: 'baz' }); + var map = new SimpleMap(); + var scope = new Scope(map); + QUnit.ok(!scope.peek('scope.vars.foo.bar'), 'vars.foo.bar === undefined'); + scope.set('scope.vars.foo', foo); + QUnit.equal(scope.peek('scope.vars.foo.bar'), 'baz', 'vars.foo.bar === baz'); + scope.set('scope.vars.foo.bar', 'quz'); + QUnit.equal(scope.peek('scope.vars.foo.bar'), 'quz', 'vars.foo.bar === quz'); + }); + QUnit.test('nested properties can be read from scope.root', function () { + var root = new SimpleMap({ bar: 'baz' }); + var map = new SimpleMap({ bar: 'abc' }); + var scope = new Scope(root).add(map); + QUnit.equal(scope.peek('scope.root.bar'), 'baz', 'root.bar === baz'); + }); + QUnit.test('special scopes are skipped if options.special !== true', function () { + var map1 = new SimpleMap({}); + var scope = new Scope(map1).add({ foo: 'two' }, { special: true }).add({}); + QUnit.equal(scope.peek('foo', { special: true }), 'two', 'foo is read from special scope'); + }); + QUnit.test('special scopes are skipped when using ../.', function () { + var obj = { foo: 'one' }; + var scope = new Scope(obj).add({ foo: 'two' }, { special: true }).add({}); + QUnit.equal(scope.peek('../.'), obj); + QUnit.equal(scope.peek('.././foo'), 'one'); + }); + QUnit.test('special scopes are skipped when using .', function () { + var map = new SimpleMap({ foo: 'one' }); + var scope = new Scope(map).add({ foo: 'two' }, { special: true }); + QUnit.equal(scope.peek('.'), map); + }); + QUnit.test('this works everywhere (#45)', function () { + var obj = { foo: 'bar' }; + var scope = new Scope(obj); + QUnit.equal(scope.get('this.foo'), 'bar'); + }); + QUnit.test('\'this\' and %context give the context', 1, function () { + var vm; + var MyMap = SimpleMap.extend({ + doSomething: function () { + QUnit.equal(this, vm, 'event callback called on context'); + } + }); + vm = new MyMap(); + var compute = new Scope(vm).computeData('this.doSomething', { + isArgument: true, + args: [] + }).compute; + compute()(); + }); + QUnit.test('that .set with ../ is able to skip notContext scopes (#43)', function () { + var instance = new SimpleMap({ prop: 0 }); + var notContextContext = { NAME: 'NOT CONTEXT' }; + var top = { NAME: 'TOP' }; + var scope = new Scope(instance).add(notContextContext, { notContext: true }).add(top); + scope.set('../prop', 1); + QUnit.equal(instance.attr('prop'), 1); + }); + test('undefined props should be a scope hit (#20)', function () { + var MyType = SimpleMap.extend('MyType', { + init: function () { + this.value = undefined; + } + }); + var EmptyType = SimpleMap.extend('EmptyType', {}); + var instance = new MyType(); + var scope = new Scope(instance).add(new EmptyType()); + var c1 = scope.computeData('../value').compute; + c1.on('change', function () { + }); + c1('BAR'); + QUnit.equal(instance.attr('value'), 'BAR'); + var instance2 = new MyType(); + var scope2 = new Scope(instance2).add(new SimpleObservable()); + var c2 = scope2.computeData('../value').compute; + c2.on('change', function () { + }); + c2('BAR'); + QUnit.equal(instance2.attr('value'), 'BAR'); + }); + QUnit.test('ScopeKeyData can.valueHasDependencies', function () { + var map = new SimpleMap({ age: 21 }); + var base = new Scope(map); + var age = base.computeData('age'); + QUnit.equal(canReflect.valueHasDependencies(age), undefined, 'undefined'); + canReflect.onValue(age, function () { + }); + QUnit.equal(canReflect.valueHasDependencies(age), true, 'undefined'); + }); + QUnit.test('get and set Priority', function () { + var map = new SimpleMap({ age: 21 }); + var base = new Scope(map); + var age = base.computeData('age'); + canReflect.setPriority(age, 5); + QUnit.equal(canReflect.getPriority(age), 5, 'set priority'); + var compute = age.compute; + QUnit.equal(canReflect.getPriority(compute), 5, 'set priority'); + }); + QUnit.test('fast path checking does not leak ObservationRecord.adds', function () { + var map = new SimpleMap({ age: 21 }); + Object.defineProperty(map, 'age', { + get: function () { + return this.attr('age'); + }, + set: function (newVal) { + this.attr('age', newVal); + } + }); + var base = new Scope(map); + var age = base.computeData('age'); + ObservationRecorder.start(); + age.get(); + var dependencies = ObservationRecorder.stop(); + QUnit.equal(dependencies.keyDependencies.size, 0, 'no key dependencies'); + QUnit.equal(dependencies.valueDependencies.size, 1, 'only sees age'); + QUnit.ok(dependencies.valueDependencies.has(age), 'only sees age'); + }); + QUnit.test('{{scope.set(...)}} works', function () { + var map = new SimpleMap({ foo: 'bar' }); + var scope = new Scope(map); + var set = scope.peek('scope@set'); + set('foo', 'baz'); + QUnit.equal(map.get('foo'), 'baz', 'map.foo updated using scope.set'); + }); + QUnit.test('can read a method from scope.viewModel', function () { + var viewModel = new SimpleMap({ + method: function () { + return 'method return value'; + } + }); + var scope = new Scope({}).add({ viewModel: viewModel }, { special: true }); + var method = scope.peek('scope.viewModel@method'); + QUnit.equal(method(), 'method return value'); + }); + QUnit.test('can read a value from scope.element', function () { + var element = { value: 'element value' }; + var scope = new Scope({}).add({ element: element }, { special: true }); + var value = scope.peek('scope.element.value'); + QUnit.equal(value, 'element value'); + }); + QUnit.test('scope.find can be used to find a value in the first scope it exists', function () { + var a = new SimpleMap({ a: 'a' }); + var b = new SimpleMap({ b: 'b' }); + var c = new SimpleMap({ c: 'c' }); + var scope = new Scope(c).add(b).add(a); + QUnit.equal(scope.find('a'), 'a', 'a'); + QUnit.equal(scope.find('b'), 'b', 'b'); + QUnit.equal(scope.find('c'), 'c', 'c'); + }); + QUnit.test('scope.find accepts readOptions', function () { + var a = new SimpleMap({ a: 'a' }); + a.func = function () { + return this; + }; + var b = new SimpleMap({ b: 'b' }); + var c = new SimpleMap({ c: 'c' }); + var scope = new Scope(c).add(b).add(a); + var aDotFunc = scope.find('func'); + QUnit.equal(aDotFunc(), a, 'a.func() got correct context'); + aDotFunc = scope.find('func', { proxyMethods: false }); + QUnit.notEqual(aDotFunc(), a, 'non-proxied a.func() got correct context'); + }); + QUnit.test('scope.read should not walk up normal scopes by default', function () { + var a = new SimpleMap({ a: 'a' }); + var b = new SimpleMap({ b: 'b' }); + var c = new SimpleMap({ c: 'c' }); + var scope = new Scope(c).add(b).add(a); + QUnit.equal(scope.read('a').value, 'a', 'a'); + QUnit.equal(scope.read('b').value, undefined, 'b'); + QUnit.equal(scope.read('c').value, undefined, 'c'); + }); + QUnit.test('scope.read should walk over special scopes', function () { + var map = new SimpleMap({ + a: 'a', + b: 'b', + c: 'c' + }); + var scope = new Scope(map).add({ d: 'd' }, { special: true }); + QUnit.equal(scope.read('a').value, 'a', 'a'); + QUnit.equal(scope.read('b').value, 'b', 'b'); + QUnit.equal(scope.read('c').value, 'c', 'c'); + }); + QUnit.test('scope.read should skip special contexts and read from notContext scope higher in the chain', function () { + var scope = new Scope({ a: 'a' }).add({ b: 'b' }, { notContext: true }).add({ c: 'c' }, { special: true }).add({ d: 'd' }, { notContext: true }).add({ e: 'e' }); + QUnit.equal(scope.read('a').value, undefined, 'a not read from normal parent context'); + QUnit.equal(scope.read('b').value, 'b', 'b read correctly from notContext parent context'); + QUnit.equal(scope.read('c').value, undefined, 'c not read from special context'); + QUnit.equal(scope.read('d').value, 'd', 'd read correctly from notContext parent context'); + QUnit.equal(scope.read('e').value, 'e', 'e read correctly'); + scope = scope.add({ f: 'f' }, { notContext: true }).add({ g: 'g' }, { special: true }).add({ h: 'h' }, { notContext: true }).add({ i: 'i' }); + QUnit.equal(scope.read('e').value, undefined, 'e not read from normal parent context'); + QUnit.equal(scope.read('f').value, 'f', 'f read correctly from notContext parent context'); + QUnit.equal(scope.read('g').value, undefined, 'g not read from special context'); + QUnit.equal(scope.read('h').value, 'h', 'h read correctly from notContext parent context'); + QUnit.equal(scope.read('i').value, 'i', 'i read correctly'); + QUnit.equal(scope.read('../a').value, undefined, '../a not read from normal parent context above normal parent context'); + QUnit.equal(scope.read('../b').value, 'b', '../b read correctly from notContext parent context above normal parent context'); + QUnit.equal(scope.read('../c').value, undefined, '../c not read from special context above normal parent context'); + QUnit.equal(scope.read('../d').value, 'd', '../d read correctly from notContext parent context above normal parent context'); + QUnit.equal(scope.read('../e').value, 'e', '../e read correctly above normal parent context'); + }); + QUnit.test('reading using ../ when there is no parent returns undefined', function () { + var scope = new Scope({}); + try { + QUnit.equal(scope.read('../foo').value, undefined, 'returns undefined'); + } catch (e) { + QUnit.ok(false, 'error occured: ' + e); + } + }); + QUnit.test('read checks templateContext helpers then global helpers after checking the scope', function () { + var map = { + scopeFunction: function () { + return 'scopeFunction'; + } + }; + var helperFunction = function () { + return 'helperFunction'; + }; + var localHelperFunction = function () { + return 'localHelperFunction'; + }; + var globalHelperCalledLocalHelperFunction = function () { + return 'global helper function called "localHelperFunction"'; + }; + var scope = new Scope(map); + canStacheHelpers.helperFunction = helperFunction; + canReflect.setKeyValue(scope.templateContext.helpers, 'localHelperFunction', localHelperFunction); + canStacheHelpers.localHelperFunction = globalHelperCalledLocalHelperFunction; + var readScopeFunction = scope.read('scopeFunction').value; + QUnit.deepEqual(readScopeFunction(), 'scopeFunction', 'scopeFunction'); + var readLocalHelperFunction = scope.read('localHelperFunction').value; + QUnit.deepEqual(readLocalHelperFunction(), 'localHelperFunction', 'localHelperFunction'); + var readHelperFunction = scope.read('helperFunction').value; + QUnit.deepEqual(readHelperFunction(), 'helperFunction', 'helperFunction'); + delete canStacheHelpers.helperFunction; + delete canStacheHelpers.localHelperFunction; + canReflect.setKeyValue(scope.templateContext.helpers, 'localHelperFunction', undefined); + }); + QUnit.test('read can handle objects stored on helpers', function () { + var scope = new Scope(); + var fakeConsole = { + log: function () { + return 'fakeConsole.log'; + }, + warn: function () { + return 'fakeConsole.warn'; + } + }; + canStacheHelpers.console = fakeConsole; + var readConsoleLog = scope.read('console.log').value; + QUnit.deepEqual(readConsoleLog(), 'fakeConsole.log', 'fakeConsole.log'); + var readConsoleWarn = scope.read('console.warn').value; + QUnit.deepEqual(readConsoleWarn(), 'fakeConsole.warn', 'fakeConsole.warn'); + delete canStacheHelpers.console; + }); + QUnit.test('scope.helpers can be used to read a helper that conflicts with a property in the scope', function () { + var map = { + myIf: function () { + return 'map.myIf'; + } + }; + var myIf = function () { + return 'global.myIf'; + }; + var scope = new Scope(map); + canStacheHelpers.myIf = myIf; + var localIf = scope.read('myIf').value; + QUnit.deepEqual(localIf(), 'map.myIf', 'scope function'); + var globalIf = scope.read('scope.helpers.myIf').value; + QUnit.deepEqual(globalIf(), 'global.myIf', 'global function'); + delete canStacheHelpers.myIf; + }); + QUnit.test('functions have correct `thisArg` so they can be called even with `proxyMethods: false`', function () { + var parent = { + name: function () { + return 'parent'; + } + }; + var child = { + name: function () { + return 'child'; + } + }; + var func = function () { + }; + var childData = { + child: child, + func: func + }; + var parentData = { + parent: parent, + func: func + }; + var scope = new Scope(parentData).add(childData); + var childName = scope.read('child.name', { proxyMethods: false }); + QUnit.equal(childName.value, child.name, 'childName.value === child.name'); + QUnit.equal(childName.thisArg, child, 'childName.thisArg === child'); + var childNameCompute = scope.computeData('child.name', { proxyMethods: false }); + Observation.temporarilyBind(childNameCompute); + QUnit.equal(childNameCompute.initialValue, child.name, 'childNameCompute.inititalValue === child.name'); + QUnit.equal(childNameCompute.thisArg, child, 'childNameCompute.thisArg === child'); + var rootFunc = scope.read('func', { proxyMethods: false }); + QUnit.equal(rootFunc.value, func, 'rootFunc.value === func'); + QUnit.equal(rootFunc.thisArg, childData, 'rootFunc.thisArg === childData'); + var myHelper = function () { + }; + canReflect.setKeyValue(scope.templateContext.helpers, 'myHelper', myHelper); + var helper = scope.read('myHelper', { proxyMethods: false }); + QUnit.equal(helper.value, myHelper, 'helper.value === func'); + QUnit.equal(helper.thisArg, undefined, 'helper.thisArg === undefined'); + var parentName = scope.read('../parent.name', { proxyMethods: false }); + QUnit.equal(parentName.value, parent.name, 'parentName.value === parent.name'); + QUnit.equal(parentName.thisArg, parent, 'parentName.thisArg === parent'); + var parentFunc = scope.read('../func', { proxyMethods: false }); + QUnit.equal(parentFunc.value, func, 'parentFunc.value === func'); + QUnit.equal(parentFunc.thisArg, parentData, 'rootFunc.thisArg === parentData'); + }); + QUnit.test('debugger is a reserved scope key for calling debugger helper', function () { + var scope = new Scope({ name: 'Kevin' }); + var debuggerHelper = function (options) { + return options.scope.read('name').value; + }; + canStacheHelpers['debugger'] = debuggerHelper; + var debuggerScopeKey = scope.compute('debugger'); + QUnit.equal(canReflect.getValue(debuggerScopeKey), 'Kevin', 'debugger called with correct helper options'); + delete canStacheHelpers['debugger']; + }); + QUnit.test('scope.vm and scope.top', function () { + var scope = new Scope({ name: 'foo' }).add({ name: 'Kevin' }, { viewModel: true }).add({ name: 'bar' }).add({ name: 'Ryan' }, { viewModel: true }).add({ name: 'baz' }); + QUnit.equal(scope.read('scope.vm.name').value, 'Ryan', 'scope.first can be used to read from the _first_ context with viewModel: true'); + QUnit.equal(scope.read('scope.top.name').value, 'Kevin', 'scope.top can be used to read from the _top_ context with viewModel: true'); + }); + testHelpers.dev.devOnlyTest('scope.root deprecation warning', function () { + var teardown = testHelpers.dev.willWarn(/`scope.root` is deprecated/); + var scope = new Scope({ foo: 'bar' }); + scope.read('scope.root'); + QUnit.equal(teardown(), 1, 'deprecation warning displayed'); + }); + testHelpers.dev.devOnlyTest('scope.getPathsForKey', function () { + var top = {}; + top[canSymbol.for('can.hasKey')] = function (key) { + return key === 'name'; + }; + var vm = { name: 'Ryan' }; + var nonVm = { name: 'Bianca' }; + var notContext = { index: 0 }; + var special = { myIndex: 0 }; + var scope = new Scope(top, null, { viewModel: true }).add(notContext, { notContext: true }).add(vm, { viewModel: true }).add(special, { special: true }).add(true).add(nonVm); + var paths = scope.getPathsForKey('name'); + QUnit.deepEqual(paths, { + 'scope.vm.name': vm, + 'scope.top.name': top, + 'name': nonVm, + '../../name': vm, + '../../../name': top + }); + }); + testHelpers.dev.devOnlyTest('scope.getPathsForKey works for functions', function () { + var top = { + name: function () { + return 'Christopher'; + } + }; + var vm = { + name: function () { + return 'Ryan'; + } + }; + var nonVm = { + name: function () { + return 'Bianca'; + } + }; + var notContext = { index: 0 }; + var special = { myIndex: 0 }; + var scope = new Scope(top, null, { viewModel: true }).add(notContext, { notContext: true }).add(vm, { viewModel: true }).add(special, { special: true }).add(true).add(nonVm); + var paths = scope.getPathsForKey('name'); + QUnit.deepEqual(paths, { + 'scope.vm.name()': vm, + 'scope.top.name()': top, + 'name()': nonVm, + '../../name()': vm, + '../../../name()': top + }); + }); + QUnit.test('scope.hasKey', function () { + var top = { foo: 'bar' }; + var vm = { bar: 'baz' }; + var nonVm = {}; + nonVm[canSymbol.for('can.hasKey')] = function (key) { + return key === 'baz'; + }; + var scope = new Scope(top, null, { viewModel: true }).add(vm, { viewModel: true }).add(nonVm); + QUnit.equal(canReflect.hasKey(scope, 'scope.top.foo'), true, 'hasKey scope.top.foo === true'); + QUnit.equal(canReflect.hasKey(scope, 'scope.top.bar'), false, 'hasKey scope.top.bar === false'); + QUnit.equal(canReflect.hasKey(scope, 'scope.vm.bar'), true, 'hasKey scope.vm.bar === true'); + QUnit.equal(canReflect.hasKey(scope, 'scope.vm.baz'), false, 'hasKey scope.vm.baz === false'); + QUnit.equal(canReflect.hasKey(scope, 'baz'), true, 'hasKey baz === true'); + QUnit.equal(canReflect.hasKey(scope, 'foo'), false, 'hasKey foo === false'); + }); + QUnit.test('read returns correct `parentHasKey` value', function () { + var vm = {}; + canReflect.assignSymbols(vm, { + 'can.hasKey': function (key) { + return key === 'foo'; + } + }); + var scope = new Scope(vm); + QUnit.ok(scope.read('foo').parentHasKey, 'parent has key \'foo\''); + QUnit.notOk(scope.read('bar').parentHasKey, 'parent does not have key \'bar\''); + }); + QUnit.test('computeData returns correct `parentHasKey` value', function () { + var vm = {}; + canReflect.assignSymbols(vm, { + 'can.hasKey': function (key) { + return key === 'foo'; + } + }); + var scope = new Scope(vm); + var fooCompute = scope.computeData('foo'); + var barCompute = scope.computeData('bar'); + fooCompute.read(); + barCompute.read(); + QUnit.ok(fooCompute.parentHasKey, 'parent has key \'foo\''); + QUnit.notOk(barCompute.parentHasKey, 'parent does not have key \'bar\''); + }); + QUnit.test('can get helpers from parent TemplateContext', function () { + var scope = new Scope(new Scope.TemplateContext({ + helpers: { + foo: function () { + } + } + })).add(new Scope.TemplateContext()).add({}); + QUnit.ok(scope.get('foo'), 'got helper'); + }); + QUnit.test('do not error when reading a missing parent context (#183)', function () { + var scope = new Scope(new Scope.TemplateContext({})).add({}, {}); + var results = scope.read('../key', {}); + QUnit.ok(results.noContextAvailable, 'no error'); + }); + QUnit.test('cloneFromRef clones meta', function () { + var scope = new Scope({}).add(new Scope.TemplateContext({})).addLetContext({ tempProp: undefined }); + var copyScope = scope.cloneFromRef(); + QUnit.deepEqual(copyScope._meta, { variable: true }); + }); + QUnit.test('scope/key walks the scope', function () { + var scope = new Scope({ + foo: 'bar', + baz: function () { + return 'quz'; + } + }).add({}).add({}); + var value = scope.peek('scope/foo'); + QUnit.equal(value, 'bar'); + value = scope.peek('@scope/baz'); + QUnit.equal(value(), 'quz'); + }); + QUnit.test('able to read partials', function () { + var myPartial = function () { + }; + var scope = new Scope(new Scope.TemplateContext({ partials: { myPartial: myPartial } })).add({}); + var result = scope.get('myPartial'); + QUnit.equal(result, myPartial, 'read the value'); + }); + require('./variable-scope-test'); + require('./scope-set-test'); + require('./scope-key-data-test'); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-view-target@4.1.2#test/test*/ +define('can-view-target@4.1.2#test/test', [ + 'require', + 'exports', + 'module', + 'can-view-target', + 'can-simple-dom', + 'steal-qunit', + 'can-globals/mutation-observer/mutation-observer' +], function (require, exports, module) { + (function (global, require, exports, module) { + var target = require('can-view-target'); + var simpleDom = require('can-simple-dom'); + var QUnit = require('steal-qunit'); + var MUTATION_OBSERVER = require('can-globals/mutation-observer/mutation-observer'); + QUnit.module('can-view-target'); + test('basics', function () { + var classCallback = function () { + equal(this.nodeName.toLowerCase(), 'h1', 'class on the right element'); + this.className = 'selected'; + }, attributesCallback = function () { + equal(this.nodeName.toLowerCase(), 'h1', 'attributes on the right element'); + }, textNodeCallback = function () { + equal(this.nodeType, 3, 'got a text node'); + this.nodeValue = 'World'; + }; + var data = target([{ + tag: 'h1', + attrs: { + 'id': 'myh1', + 'class': classCallback + }, + attributes: [attributesCallback], + children: [{ + tag: 'span', + children: [ + 'Hello ', + textNodeCallback, + '!' + ] + }] + }]); + equal(data.clone.childNodes.length, 1, 'there is one child'); + var h1 = data.clone.childNodes[0]; + equal(h1.nodeName.toLowerCase(), 'h1', 'there is one h1'); + equal(h1.id, 'myh1', 'the h1 has the right id'); + equal(h1.childNodes.length, 1, 'the h1 has span'); + equal(h1.childNodes[0].childNodes.length, 3, 'the span has 3 children'); + deepEqual(data.paths, [{ + path: [0], + callbacks: [ + { callback: classCallback }, + { callback: attributesCallback } + ], + paths: [{ + path: [ + 0, + 1 + ], + callbacks: [{ callback: target.keepsTextNodes ? textNodeCallback : data.paths[0].paths[0].callbacks[0].callback }] + }] + }]); + var result = data.hydrate(); + var newH1 = result.childNodes[0]; + equal(newH1.className, 'selected', 'got selected class name'); + equal(newH1.innerHTML.toLowerCase(), 'hello world!'); + }); + test('replacing items', function () { + var data = target([ + function () { + this.parentNode.insertBefore(document.createTextNode('inserted'), this.nextSibling); + }, + 'hi', + function () { + equal(this.previousSibling.nodeValue, 'hi', 'previous is as expected'); + } + ]); + data.hydrate(); + }); + test('comments', function () { + var data = target([ + { tag: 'h1' }, + { comment: 'foo bar' } + ]); + var node = data.clone.childNodes[1]; + equal(node.nodeValue, 'foo bar', 'node value is right'); + equal(node.nodeType, 8, 'node is a comment'); + }); + test('paths should be run in reverse order (#966)', function () { + var data = target([{ + tag: 'h1', + attributes: [function () { + }], + children: [ + function () { + this.parentNode.insertBefore(document.createElement('div'), this.nextSibling); + }, + { + tag: 'span', + children: [function () { + equal(this.nodeType, 3, 'got an element'); + }] + } + ] + }]); + data.hydrate(); + }); + test('renderToVirtualDOM', function () { + var simpleDocument = new simpleDom.Document(); + var innerData = target([{ tag: 'span' }], simpleDocument); + var outerData = target([{ + tag: 'h1', + children: [ + function (data) { + this.parentNode.insertBefore(innerData.hydrate(data), this); + this.parentNode.removeChild(this); + }, + 'foo' + ] + }], simpleDocument); + var out = outerData.hydrate({ foo: true }); + equal(out.firstChild.nodeName, 'H1'); + equal(out.firstChild.firstChild.nodeName, 'SPAN'); + equal(out.firstChild.lastChild.nodeValue, 'foo'); + }); + test('cloneNode works in IE11', function () { + var frag = document.createDocumentFragment(); + var text = document.createTextNode('some-text'); + var MO = MUTATION_OBSERVER(); + var observer; + frag.appendChild(text); + var clone = target.cloneNode(frag); + equal(clone.childNodes.length, 1, 'cloneNode should work'); + if (MO) { + observer = new MO(function (mutations) { + }); + observer.observe(document.documentElement, { + childList: true, + subtree: true + }); + clone = target.cloneNode(frag); + equal(clone.childNodes.length, 1, 'cloneNode should work after creating MutationObserver'); + } + }); + test('cloneNode keeps non-default element namespace', function () { + var frag = document.createDocumentFragment(); + var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); + frag.appendChild(svg); + var clone = target.cloneNode(frag); + equal(clone.firstChild.namespaceURI, 'http://www.w3.org/2000/svg', 'cloneNode should keep non-default element namespace'); + }); + QUnit.test('SVG namespaceURI', function () { + var data = target([{ + tag: 'svg', + attrs: { + 'xmlns': { + value: 'http://www.w3.org/2000/svg', + namespaceURI: 'http://www.w3.org/2000/xmlns/' + } + } + }]); + var frag = data.hydrate(); + QUnit.equal(frag.firstChild.getAttributeNode('xmlns').namespaceURI, 'http://www.w3.org/2000/xmlns/'); + }); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-stache-converters@4.2.5#can-stache-converters*/ +define('can-stache-converters@4.2.5#can-stache-converters', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-stache', + 'can-string-to-any', + 'can-log/dev/dev', + 'can-stache-bindings', + 'can-stache-helpers' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var stache = require('can-stache'); + var stringToAny = require('can-string-to-any'); + var dev = require('can-log/dev/dev'); + require('can-stache-bindings'); + var stacheHelpers = require('can-stache-helpers'); + var shouldPop = false; + stache('{{echo(args(1))}}')({ + echo: function () { + }, + args: function () { + shouldPop = arguments.length > 1; + } + }); + stache.registerConverter('boolean-to-inList', { + get: function (item, list) { + if (!list) { + return false; + } else { + return list.indexOf(item) !== -1; + } + }, + set: function (newVal, item, list) { + if (!list) { + return; + } + if (!newVal) { + var idx = list.indexOf(item); + if (idx !== -1) { + list.splice(idx, 1); + } + } else { + list.push(item); + } + } + }); + var converters = { + 'string-to-any': { + get: function (obs) { + return '' + canReflect.getValue(obs); + }, + set: function (newVal, obs) { + var converted = stringToAny(newVal); + canReflect.setValue(obs, converted); + } + }, + 'index-to-selected': { + get: function (item, list) { + var val = canReflect.getValue(item); + var idx = canReflect.getValue(list).indexOf(val); + return idx; + }, + set: function (idx, item, list) { + var newVal = canReflect.getValue(list)[idx]; + canReflect.setValue(item, newVal); + } + }, + 'selected-to-index': { + get: function (idx, list) { + var val = canReflect.getValue(idx), listValue = canReflect.getValue(list); + var item = listValue[val]; + return item; + }, + set: function (item, idx, list) { + var newVal = canReflect.getValue(list).indexOf(item); + canReflect.setValue(idx, newVal); + } + }, + 'either-or': { + get: function (chosen, a, b) { + var chosenVal = canReflect.getValue(chosen), aValue = canReflect.getValue(a), bValue = canReflect.getValue(b); + var matchA = aValue === chosenVal; + var matchB = bValue === chosenVal; + if (!matchA && !matchB) { + return; + } else { + return matchA; + } + }, + set: function (newVal, chosen, a, b) { + var setVal = newVal ? canReflect.getValue(a) : canReflect.getValue(b); + canReflect.setValue(chosen, setVal); + } + }, + 'equal': { + get: function () { + var args = canReflect.toArray(arguments); + if (shouldPop) { + args.pop(); + } + if (args.length > 1) { + var comparer = canReflect.getValue(args.pop()); + return args.every(function (obs) { + var value = canReflect.getValue(obs); + return value === comparer; + }); + } + }, + set: function () { + var args = canReflect.toArray(arguments); + if (shouldPop) { + args.pop(); + } + if (args.length > 2) { + var b = args.shift(); + var comparer = canReflect.getValue(args.pop()); + if (b) { + for (var i = 0; i < args.length; i++) { + canReflect.setValue(args[i], comparer); + } + } + } + } + } + }; + stache.addConverter(converters); + if (!stacheHelpers.not) { + stache.addConverter('not', { + get: function (obs) { + return !canReflect.getValue(obs); + }, + set: function (newVal, obs) { + canReflect.setValue(obs, !newVal); + } + }); + } + module.exports = converters; +}); +/*can-stache-converters@4.2.5#test/boolean-to-inList_test*/ +define('can-stache-converters@4.2.5#test/boolean-to-inList_test', [ + 'require', + 'exports', + 'module', + 'can-stache-converters', + 'can-define/list/list', + 'can-define/map/map', + 'can-stache', + 'can-dom-events', + 'can-reflect', + 'steal-qunit' +], function (require, exports, module) { + require('can-stache-converters'); + var DefineList = require('can-define/list/list'); + var DefineMap = require('can-define/map/map'); + var stache = require('can-stache'); + var domEvents = require('can-dom-events'); + var canReflect = require('can-reflect'); + var QUnit = require('steal-qunit'); + QUnit.module('boolean-to-inList', { + setup: function () { + this.fixture = document.getElementById('qunit-fixture'); + } + }); + QUnit.test('Works with checkboxes', function () { + var template = stache(''); + var map = new DefineMap({ + item: 2, + list: new DefineList([ + 1, + 2, + 3 + ]) + }); + var frag = template(map); + var input = frag.firstChild; + QUnit.ok(input.checked, 'it is initially checked'); + QUnit.equal(map.list.indexOf(2), 1, 'two is in the list'); + input.checked = false; + domEvents.dispatch(input, 'change'); + QUnit.equal(map.list.indexOf(2), -1, 'No longer in the list'); + map.item = 3; + QUnit.ok(input.checked, '3 is in the list'); + map.item = 5; + QUnit.ok(!input.checked, '5 is not in the list'); + map.list.push(5); + QUnit.ok(input.checked, 'Now 5 is in the list'); + map.item = 6; + input.checked = true; + domEvents.dispatch(input, 'change'); + QUnit.equal(map.list.indexOf(6), 3, 'pushed into the list'); + }); + QUnit.test('If there is no list, treated as false', function () { + var template = stache(''); + var map = new DefineMap({ + item: 2, + list: undefined + }); + var frag = template(map); + var input = frag.firstChild; + QUnit.ok(!input.checked, 'not checked because there is no list'); + input.checked = true; + domEvents.dispatch(input, 'change'); + QUnit.ok(true, 'no errors thrown'); + }); + QUnit.test('works with radio buttons', function () { + var template = stache('
      '); + var map = new DefineMap({ names: ['Wilbur'] }); + var frag = template(map); + var radioOne = frag.firstChild.firstChild; + var radioTwo = radioOne.nextSibling; + this.fixture.appendChild(frag); + QUnit.equal(radioOne.checked, false, 'Matthew not checked'); + QUnit.equal(radioTwo.checked, true, 'Wilbur is checked'); + radioOne.checked = true; + domEvents.dispatch(radioOne, 'change'); + QUnit.equal(radioOne.checked, true, 'Matthew is checked'); + QUnit.equal(radioTwo.checked, false, 'Wilbur is not checked'); + }); +}); +/*can-stache-converters@4.2.5#test/index-to-selected_test*/ +define('can-stache-converters@4.2.5#test/index-to-selected_test', [ + 'require', + 'exports', + 'module', + 'can-stache-converters', + 'can-define/list/list', + 'can-define/map/map', + 'can-dom-events', + 'can-stache', + 'can-reflect', + 'steal-qunit' +], function (require, exports, module) { + require('can-stache-converters'); + var DefineList = require('can-define/list/list'); + var DefineMap = require('can-define/map/map'); + var domEvents = require('can-dom-events'); + var stache = require('can-stache'); + var canReflect = require('can-reflect'); + var QUnit = require('steal-qunit'); + QUnit.module('index-to-selected'); + QUnit.test('chooses select option by the index from a list', function () { + var template = stache(''); + var map = new DefineMap({ + person: 'Anne', + people: [ + 'Matthew', + 'Anne', + 'Wilbur' + ] + }); + var select = template(map).firstChild; + QUnit.equal(select.value, 1, 'initially set to the first value'); + select.value = 2; + domEvents.dispatch(select, 'change'); + QUnit.equal(map.person, 'Wilbur', 'now it is me'); + map.person = map.people.item(0); + QUnit.equal(select.value, 0, 'set back'); + select.value = 'none'; + domEvents.dispatch(select, 'change'); + QUnit.equal(map.person, undefined, 'now undefined because not in the list'); + }); + QUnit.test('chooses select option by the index from a list without ~', function () { + var template = stache(''); + var map = new DefineMap({ + person: 'Anne', + people: [ + 'Matthew', + 'Anne', + 'Wilbur' + ] + }); + var select = template(map).firstChild; + QUnit.equal(select.value, 1, 'initially set to the first value'); + select.value = 2; + domEvents.dispatch(select, 'change'); + QUnit.equal(map.person, 'Wilbur', 'now it is me'); + map.person = map.people.item(0); + QUnit.equal(select.value, 0, 'set back'); + select.value = 'none'; + domEvents.dispatch(select, 'change'); + QUnit.equal(map.person, undefined, 'now undefined because not in the list'); + }); +}); +/*can-stache-converters@4.2.5#test/selected-to-index_test*/ +define('can-stache-converters@4.2.5#test/selected-to-index_test', [ + 'require', + 'exports', + 'module', + 'can-stache-converters', + 'can-define/map/map', + 'can-dom-events', + 'can-stache', + 'steal-qunit' +], function (require, exports, module) { + require('can-stache-converters'); + var DefineMap = require('can-define/map/map'); + var domEvents = require('can-dom-events'); + var stache = require('can-stache'); + var QUnit = require('steal-qunit'); + QUnit.module('selected-to-index'); + QUnit.test('sets index by the value from a list', function () { + var template = stache(''); + var map = new DefineMap({ + index: '1', + people: [ + 'Matthew', + 'Anne', + 'Wilbur' + ] + }); + var input = template(map).firstChild; + QUnit.equal(input.value, 'Anne', 'initially set to the first value'); + input.value = 'Wilbur'; + domEvents.dispatch(input, 'change'); + QUnit.equal(map.index, '2', 'now it is me'); + map.index = '0'; + QUnit.equal(input.value, 'Matthew', 'set back'); + input.value = 'none'; + domEvents.dispatch(input, 'change'); + QUnit.equal(map.index, -1, 'now -1 because not in the list'); + }); + QUnit.test('sets index by the value from a list without ~', function () { + var template = stache(''); + var map = new DefineMap({ + index: '1', + people: [ + 'Matthew', + 'Anne', + 'Wilbur' + ] + }); + var input = template(map).firstChild; + QUnit.equal(input.value, 'Anne', 'initially set to the first value'); + input.value = 'Wilbur'; + domEvents.dispatch(input, 'change'); + QUnit.equal(map.index, '2', 'now it is me'); + map.index = '0'; + QUnit.equal(input.value, 'Matthew', 'set back'); + input.value = 'none'; + domEvents.dispatch(input, 'change'); + QUnit.equal(map.index, -1, 'now -1 because not in the list'); + }); +}); +/*can-stache-converters@4.2.5#test/string-to-any_test*/ +define('can-stache-converters@4.2.5#test/string-to-any_test', [ + 'require', + 'exports', + 'module', + 'can-stache-converters', + 'can-define/list/list', + 'can-define/map/map', + 'can-dom-events', + 'can-stache', + 'can-reflect', + 'steal-qunit' +], function (require, exports, module) { + require('can-stache-converters'); + var DefineList = require('can-define/list/list'); + var DefineMap = require('can-define/map/map'); + var domEvents = require('can-dom-events'); + var stache = require('can-stache'); + var canReflect = require('can-reflect'); + var QUnit = require('steal-qunit'); + QUnit.module('string-to-any'); + QUnit.test('Works on all the types', function () { + var types = { + '22.3': 22.3, + 'foo': 'foo', + 'true': true, + 'false': false, + 'undefined': undefined, + 'null': null, + 'Infinity': Infinity, + 'NaN': { + expected: NaN, + equalityTest: function (a) { + return isNaN(a); + } + } + }; + var defaultEquality = function (a, b) { + return a === b; + }; + canReflect.eachKey(types, function (expected, type) { + var template = stache(''); + var map = new DefineMap({ val: 'test' }); + var frag = template(map); + var select = frag.firstChild; + var option = select.firstChild.nextSibling; + var equality = defaultEquality; + if (expected != null && expected.equalityTest) { + equality = expected.equalityTest; + expected = expected.expected; + } + select.value = type; + domEvents.dispatch(select, 'change'); + QUnit.ok(equality(map.val, expected), 'map\'s value updated to: ' + type); + map.val = 'test'; + map.val = expected; + QUnit.equal(select.value, type, 'select\'s value updated to: ' + type); + }); + }); + QUnit.test('Works on all the types without ~', function () { + var types = { + '22.3': 22.3, + 'foo': 'foo', + 'true': true, + 'false': false, + 'undefined': undefined, + 'null': null, + 'Infinity': Infinity, + 'NaN': { + expected: NaN, + equalityTest: function (a) { + return isNaN(a); + } + } + }; + var defaultEquality = function (a, b) { + return a === b; + }; + canReflect.eachKey(types, function (expected, type) { + var template = stache(''); + var map = new DefineMap({ val: 'test' }); + var frag = template(map); + var select = frag.firstChild; + var option = select.firstChild.nextSibling; + var equality = defaultEquality; + if (expected != null && expected.equalityTest) { + equality = expected.equalityTest; + expected = expected.expected; + } + select.value = type; + domEvents.dispatch(select, 'change'); + QUnit.ok(equality(map.val, expected), 'map\'s value updated to: ' + type); + map.val = 'test'; + map.val = expected; + QUnit.equal(select.value, type, 'select\'s value updated to: ' + type); + }); + }); +}); +/*can-stache-converters@4.2.5#test/not_test*/ +define('can-stache-converters@4.2.5#test/not_test', [ + 'require', + 'exports', + 'module', + 'can-stache-converters', + 'can-define/list/list', + 'can-define/map/map', + 'can-dom-events', + 'can-stache', + 'steal-qunit' +], function (require, exports, module) { + require('can-stache-converters'); + var DefineList = require('can-define/list/list'); + var DefineMap = require('can-define/map/map'); + var domEvents = require('can-dom-events'); + var stache = require('can-stache'); + var QUnit = require('steal-qunit'); + QUnit.module('not'); + QUnit.test('saves the inverse of the selected value without ~ (#68)', function () { + var template = stache(''); + var map = new DefineMap({ val: true }); + var input = template(map).firstChild; + QUnit.equal(input.checked, false, 'initially false'); + map.val = false; + QUnit.equal(input.checked, true, 'true because map val is false'); + input.checked = false; + domEvents.dispatch(input, 'change'); + QUnit.equal(map.val, true, 'map is now true because checkbox is false'); + }); + QUnit.test('saves the inverse of the selected value', function () { + var template = stache(''); + var map = new DefineMap({ val: true }); + var input = template(map).firstChild; + QUnit.equal(input.checked, false, 'initially false'); + map.val = false; + QUnit.equal(input.checked, true, 'true because map val is false'); + input.checked = false; + domEvents.dispatch(input, 'change'); + QUnit.equal(map.val, true, 'map is now true because checkbox is false'); + }); + QUnit.test('works with boolean-to-inList', function () { + var template = stache(''); + var map = new DefineMap({ + item: 2, + list: new DefineList([ + 1, + 2, + 3 + ]) + }); + var input = template(map).firstChild; + QUnit.equal(input.checked, false, 'not checked because it is in the list'); + map.item = 4; + QUnit.equal(input.checked, true, 'checked because not in the list'); + input.checked = false; + domEvents.dispatch(input, 'change'); + QUnit.equal(map.list.indexOf(4), 3, 'it was pushed into the list'); + map.list.splice(3, 1); + QUnit.equal(input.checked, true, 'now it\'s checked because not in the list'); + }); +}); +/*can-compute@4.1.0#proto-compute*/ +define('can-compute@4.1.0#proto-compute', [ + 'require', + 'exports', + 'module', + 'can-observation', + 'can-observation-recorder', + 'can-event-queue/map/map', + 'can-stache-key', + 'can-key/get/get', + 'can-assign', + 'can-reflect', + 'can-single-reference' +], function (require, exports, module) { + 'use strict'; + var Observation = require('can-observation'); + var ObservationRecorder = require('can-observation-recorder'); + var eventQueue = require('can-event-queue/map/map'); + var observeReader = require('can-stache-key'); + var getObject = require('can-key/get/get'); + var assign = require('can-assign'); + var canReflect = require('can-reflect'); + var singleReference = require('can-single-reference'); + var Compute = function (getterSetter, context, eventName, bindOnce) { + var args = []; + for (var i = 0, arglen = arguments.length; i < arglen; i++) { + args[i] = arguments[i]; + } + var contextType = typeof args[1]; + if (typeof args[0] === 'function') { + this._setupGetterSetterFn(args[0], args[1], args[2], args[3]); + } else if (args[1] !== undefined) { + if (contextType === 'string' || contextType === 'number') { + var isListLike = canReflect.isObservableLike(args[0]) && canReflect.isListLike(args[0]); + var isMapLike = canReflect.isObservableLike(args[0]) && canReflect.isMapLike(args[0]); + if (isMapLike || isListLike) { + var map = args[0]; + var propertyName = args[1]; + var mapGetterSetter = function (newValue) { + if (arguments.length) { + observeReader.set(map, propertyName, newValue); + } else { + if (isListLike) { + observeReader.get(map, 'length'); + } + return observeReader.get(map, '' + propertyName); + } + }; + this._setupGetterSetterFn(mapGetterSetter, args[1], args[2], args[3]); + } else { + this._setupProperty(args[0], args[1], args[2]); + } + } else if (contextType === 'function') { + this._setupSetter(args[0], args[1], args[2]); + } else { + if (args[1] && args[1].fn) { + this._setupAsyncCompute(args[0], args[1]); + } else { + this._setupSettings(args[0], args[1]); + } + } + } else { + this._setupSimpleValue(args[0]); + } + this._args = args; + this._primaryDepth = 0; + this.isComputed = true; + }; + var updateOnChange = function (compute, newValue, oldValue, batchNum) { + var valueChanged = newValue !== oldValue && !(newValue !== newValue && oldValue !== oldValue); + if (valueChanged) { + compute.dispatch({ + type: 'change', + batchNum: batchNum + }, [ + newValue, + oldValue + ]); + } + }; + var setupComputeHandlers = function (compute, func, context) { + var observation = new Observation(func, context, compute); + var updater = compute.updater.bind(compute); + compute.observation = observation; + return { + _on: function () { + canReflect.onValue(observation, updater, 'notify'); + if (observation.hasOwnProperty('_value')) { + compute.value = observation._value; + } else { + compute.value = observation.value; + } + }, + _off: function () { + canReflect.offValue(observation, updater, 'notify'); + }, + getDepth: function () { + return observation.getDepth(); + } + }; + }; + eventQueue(Compute.prototype); + assign(Compute.prototype, { + setPrimaryDepth: function (depth) { + this._primaryDepth = depth; + }, + _setupGetterSetterFn: function (getterSetter, context, eventName) { + this._set = context ? getterSetter.bind(context) : getterSetter; + this._get = context ? getterSetter.bind(context) : getterSetter; + this._canObserve = eventName === false ? false : true; + var handlers = setupComputeHandlers(this, getterSetter, context || this); + assign(this, handlers); + }, + _setupProperty: function (target, propertyName, eventName) { + var self = this, handler; + handler = function () { + self.updater(self._get(), self.value); + }; + this._get = function () { + return getObject(target, propertyName); + }; + this._set = function (value) { + var properties = propertyName.split('.'), leafPropertyName = properties.pop(); + if (properties.length) { + var targetProperty = getObject(target, properties.join('.')); + targetProperty[leafPropertyName] = value; + } else { + target[propertyName] = value; + } + }; + this._on = function (update) { + eventQueue.on.call(target, eventName || propertyName, handler); + this.value = this._get(); + }; + this._off = function () { + return eventQueue.off.call(target, eventName || propertyName, handler); + }; + }, + _setupSetter: function (initialValue, setter, eventName) { + this.value = initialValue; + this._set = setter; + assign(this, eventName); + }, + _setupSettings: function (initialValue, settings) { + this.value = initialValue; + this._set = settings.set || this._set; + this._get = settings.get || this._get; + if (!settings.__selfUpdater) { + var self = this, oldUpdater = this.updater; + this.updater = function () { + oldUpdater.call(self, self._get(), self.value); + }; + } + this._on = settings.on ? settings.on : this._on; + this._off = settings.off ? settings.off : this._off; + }, + _setupAsyncCompute: function (initialValue, settings) { + var self = this; + var getter = settings.fn; + var bindings; + this.value = initialValue; + this._setUpdates = true; + this.lastSetValue = new Compute(initialValue); + this._set = function (newVal) { + if (newVal === self.lastSetValue.get()) { + return this.value; + } + return self.lastSetValue.set(newVal); + }; + this._get = function () { + return getter.call(settings.context, self.lastSetValue.get()); + }; + if (getter.length === 0) { + bindings = setupComputeHandlers(this, getter, settings.context); + } else if (getter.length === 1) { + bindings = setupComputeHandlers(this, function () { + return getter.call(settings.context, self.lastSetValue.get()); + }, settings); + } else { + var oldUpdater = this.updater, resolve = ObservationRecorder.ignore(function (newVal) { + oldUpdater.call(self, newVal, self.value); + }); + this.updater = function (newVal) { + oldUpdater.call(self, newVal, self.value); + }; + bindings = setupComputeHandlers(this, function () { + var res = getter.call(settings.context, self.lastSetValue.get(), resolve); + return res !== undefined ? res : this.value; + }, this); + } + assign(this, bindings); + }, + _setupSimpleValue: function (initialValue) { + this.value = initialValue; + }, + _eventSetup: ObservationRecorder.ignore(function () { + this.bound = true; + this._on(this.updater); + }), + _eventTeardown: function () { + this._off(this.updater); + this.bound = false; + }, + clone: function (context) { + if (context && typeof this._args[0] === 'function') { + this._args[1] = context; + } else if (context) { + this._args[2] = context; + } + return new Compute(this._args[0], this._args[1], this._args[2], this._args[3]); + }, + _on: function () { + }, + _off: function () { + }, + get: function () { + var recordingObservation = ObservationRecorder.isRecording(); + if (recordingObservation && this._canObserve !== false) { + ObservationRecorder.add(this, 'change'); + if (!this.bound) { + Compute.temporarilyBind(this); + } + } + if (this.bound) { + if (this.observation) { + return this.observation.get(); + } else { + return this.value; + } + } else { + return this._get(); + } + }, + _get: function () { + return this.value; + }, + set: function (newVal) { + var old = this.value; + var setVal = this._set(newVal, old); + if (this._setUpdates) { + return this.value; + } + if (this.hasDependencies) { + return this._get(); + } + this.updater(setVal === undefined ? this._get() : setVal, old); + return this.value; + }, + _set: function (newVal) { + return this.value = newVal; + }, + updater: function (newVal, oldVal, batchNum) { + this.value = newVal; + var observation = this.observation; + if (observation) { + if (observation.hasOwnProperty('_value')) { + observation._value = newVal; + } else { + observation.value = newVal; + } + } + updateOnChange(this, newVal, oldVal, batchNum); + }, + toFunction: function () { + return this._computeFn.bind(this); + }, + _computeFn: function (newVal) { + if (arguments.length) { + return this.set(newVal); + } + return this.get(); + } + }); + Compute.prototype.on = Compute.prototype.bind = Compute.prototype.addEventListener; + Compute.prototype.off = Compute.prototype.unbind = Compute.prototype.removeEventListener; + var hasDependencies = function hasDependencies() { + return this.observation && this.observation.hasDependencies(); + }; + Object.defineProperty(Compute.prototype, 'hasDependencies', { get: hasDependencies }); + Compute.temporarilyBind = Observation.temporarilyBind; + Compute.async = function (initialValue, asyncComputer, context) { + return new Compute(initialValue, { + fn: asyncComputer, + context: context + }); + }; + Compute.truthy = function (compute) { + return new Compute(function () { + var res = compute.get(); + if (typeof res === 'function') { + res = res.get(); + } + return !!res; + }); + }; + canReflect.assignSymbols(Compute.prototype, { + 'can.isValueLike': true, + 'can.isMapLike': false, + 'can.isListLike': false, + 'can.setValue': Compute.prototype.set, + 'can.getValue': Compute.prototype.get, + 'can.valueHasDependencies': hasDependencies, + 'can.onValue': function onValue(handler, queue) { + function translationHandler(ev, newValue, oldValue) { + handler(newValue, oldValue); + } + singleReference.set(handler, this, translationHandler); + this.addEventListener('change', translationHandler, queue); + }, + 'can.offValue': function offValue(handler, queue) { + this.removeEventListener('change', singleReference.getAndDelete(handler, this), queue); + }, + 'can.getValueDependencies': function getValueDependencies() { + var ret; + if (this.observation) { + ret = { valueDependencies: new Set([this.observation]) }; + } + return ret; + } + }); + module.exports = exports = Compute; +}); +/*can-compute@4.1.0#can-compute*/ +define('can-compute@4.1.0#can-compute', [ + 'require', + 'exports', + 'module', + './proto-compute', + 'can-namespace', + 'can-single-reference', + 'can-reflect/reflections/get-set/get-set', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var Compute = require('./proto-compute'); + var namespace = require('can-namespace'); + var singleReference = require('can-single-reference'); + var canReflect = require('can-reflect/reflections/get-set/get-set'); + var canSymbol = require('can-symbol'); + var canOnValueSymbol = canSymbol.for('can.onValue'), canOffValueSymbol = canSymbol.for('can.offValue'), canGetValue = canSymbol.for('can.getValue'), canSetValue = canSymbol.for('can.setValue'), isValueLike = canSymbol.for('can.isValueLike'), isMapLike = canSymbol.for('can.isMapLike'), isListLike = canSymbol.for('can.isListLike'), isFunctionLike = canSymbol.for('can.isFunctionLike'), canValueHasDependencies = canSymbol.for('can.valueHasDependencies'), canGetValueDependencies = canSymbol.for('can.getValueDependencies'); + var addEventListener = function (ev, handler) { + var compute = this; + var translationHandler; + if (handler) { + translationHandler = function () { + handler.apply(compute, arguments); + }; + singleReference.set(handler, this, translationHandler); + } + return compute.computeInstance.addEventListener(ev, translationHandler); + }; + var removeEventListener = function (ev, handler) { + var args = []; + if (typeof ev !== 'undefined') { + args.push(ev); + if (typeof handler !== 'undefined') { + args.push(singleReference.getAndDelete(handler, this)); + } + } + return this.computeInstance.removeEventListener.apply(this.computeInstance, args); + }; + var onValue = function (handler, queue) { + return this.computeInstance[canOnValueSymbol](handler, queue); + }, offValue = function (handler, queue) { + return this.computeInstance[canOffValueSymbol](handler, queue); + }, getValue = function () { + return this.computeInstance.get(); + }, setValue = function (value) { + return this.computeInstance.set(value); + }, hasDependencies = function () { + return this.computeInstance.hasDependencies; + }, getDependencies = function () { + return this.computeInstance[canGetValueDependencies](); + }; + var COMPUTE = function (getterSetter, context, eventName, bindOnce) { + function compute(val) { + if (arguments.length) { + return compute.computeInstance.set(val); + } + return compute.computeInstance.get(); + } + compute.computeInstance = new Compute(getterSetter, context, eventName, bindOnce); + compute.on = compute.bind = compute.addEventListener = addEventListener; + compute.off = compute.unbind = compute.removeEventListener = removeEventListener; + compute.isComputed = compute.computeInstance.isComputed; + compute.clone = function (ctx) { + if (typeof getterSetter === 'function') { + context = ctx; + } + return COMPUTE(getterSetter, context, ctx, bindOnce); + }; + canReflect.set(compute, canOnValueSymbol, onValue); + canReflect.set(compute, canOffValueSymbol, offValue); + canReflect.set(compute, canGetValue, getValue); + canReflect.set(compute, canSetValue, setValue); + canReflect.set(compute, isValueLike, true); + canReflect.set(compute, isMapLike, false); + canReflect.set(compute, isListLike, false); + canReflect.set(compute, isFunctionLike, false); + canReflect.set(compute, canValueHasDependencies, hasDependencies); + canReflect.set(compute, canGetValueDependencies, getDependencies); + return compute; + }; + COMPUTE.truthy = function (compute) { + return COMPUTE(function () { + var res = compute(); + return !!res; + }); + }; + COMPUTE.async = function (initialValue, asyncComputer, context) { + return COMPUTE(initialValue, { + fn: asyncComputer, + context: context + }); + }; + COMPUTE.temporarilyBind = Compute.temporarilyBind; + module.exports = namespace.compute = COMPUTE; +}); +/*can-stache-converters@4.2.5#test/either-or_test*/ +define('can-stache-converters@4.2.5#test/either-or_test', [ + 'require', + 'exports', + 'module', + 'can-stache-converters', + 'can-compute', + 'can-define/map/map', + 'can-dom-events', + 'can-stache', + 'steal-qunit' +], function (require, exports, module) { + require('can-stache-converters'); + var compute = require('can-compute'); + var DefineMap = require('can-define/map/map'); + var domEvents = require('can-dom-events'); + var stache = require('can-stache'); + var QUnit = require('steal-qunit'); + QUnit.module('either-or'); + QUnit.test('can bind to a checkbox', function () { + var renderer = stache(''); + var map = new DefineMap({ pref: 'Star Trek' }); + var input = renderer(map).firstChild; + QUnit.equal(input.checked, true, 'initial value is right'); + input.checked = false; + domEvents.dispatch(input, 'change'); + QUnit.equal(map.pref, 'Star Wars', 'changed because input changed'); + map.pref = 'Star Trek'; + QUnit.equal(input.checked, true, 'changed because map changed'); + }); + QUnit.test('initial null selection', function () { + var renderer = stache(''); + var map = new DefineMap({ pref: null }); + var input = renderer(map).firstChild; + QUnit.equal(input.checked, false, 'checkbox is unchecked'); + QUnit.strictEqual(map.pref, 'No', 'null value changed to falsey case by checkbox'); + input.checked = true; + domEvents.dispatch(input, 'change'); + QUnit.equal(map.pref, 'Yes', 'map updated because check was checked'); + }); + QUnit.test('initial undefined selection', function () { + var renderer = stache(''); + var map = new DefineMap({ pref: undefined }); + var input = renderer(map).firstChild; + QUnit.equal(input.checked, false, 'checkbox is unchecked'); + QUnit.strictEqual(map.pref, 'No', 'undefined value changed to falsey case by checkbox'); + input.checked = true; + domEvents.dispatch(input, 'change'); + QUnit.equal(map.pref, 'Yes', 'map updated because check was checked'); + }); + QUnit.test('initial no match selection', function () { + var renderer = stache(''); + var map = new DefineMap({ pref: 'fubar' }); + var input = renderer(map).firstChild; + QUnit.equal(input.checked, false, 'checkbox is unchecked'); + QUnit.strictEqual(map.pref, 'No', 'fubar value changed to falsey case by checkbox'); + input.checked = true; + domEvents.dispatch(input, 'change'); + QUnit.equal(map.pref, 'Yes', 'map updated because check was checked'); + }); + QUnit.test('supports computes', function () { + var renderer = stache(''); + var map = new DefineMap({ + pref: compute('Maybe'), + a: compute('Yes'), + b: compute('No') + }); + var input = renderer(map).firstChild; + QUnit.equal(input.checked, false, 'checkbox is unchecked'); + QUnit.strictEqual(map.pref(), 'No', 'chosen value changed to falsey case by checkbox'); + input.checked = true; + domEvents.dispatch(input, 'change'); + QUnit.equal(map.pref(), 'Yes', 'map updated because check was checked'); + input.checked = false; + domEvents.dispatch(input, 'change'); + QUnit.equal(map.pref(), 'No', 'map updated because check was unchecked'); + }); + QUnit.test('supports computes without ~', function () { + var renderer = stache(''); + var map = new DefineMap({ + pref: compute('Maybe'), + a: compute('Yes'), + b: compute('No') + }); + var input = renderer(map).firstChild; + QUnit.equal(input.checked, false, 'checkbox is unchecked'); + QUnit.strictEqual(map.pref(), 'No', 'chosen value changed to falsey case by checkbox'); + input.checked = true; + domEvents.dispatch(input, 'change'); + QUnit.equal(map.pref(), 'Yes', 'map updated because check was checked'); + input.checked = false; + domEvents.dispatch(input, 'change'); + QUnit.equal(map.pref(), 'No', 'map updated because check was unchecked'); + }); +}); +/*can-stache-converters@4.2.5#test/equal_test*/ +define('can-stache-converters@4.2.5#test/equal_test', [ + 'require', + 'exports', + 'module', + 'can-stache-converters', + 'can-compute', + 'can-dom-events', + 'can-stache', + 'can-define/list/list', + 'can-define/map/map', + 'steal-qunit' +], function (require, exports, module) { + require('can-stache-converters'); + var compute = require('can-compute'); + var domEvents = require('can-dom-events'); + var stache = require('can-stache'); + var DefineList = require('can-define/list/list'); + var DefineMap = require('can-define/map/map'); + var QUnit = require('steal-qunit'); + QUnit.module('can-stache-converters: equal'); + QUnit.test('Basics works', function () { + var template = stache(''); + var attending = compute('yes'); + var yes = template({ attending: attending }).firstChild, no = yes.nextSibling; + QUnit.equal(yes.checked, true, 'initially a yes'); + QUnit.equal(no.checked, false, 'initially unchecked'); + attending('no'); + QUnit.equal(yes.checked, false, 'now not checked'); + QUnit.equal(no.checked, true, 'now checked'); + yes.checked = true; + domEvents.dispatch(yes, 'change'); + QUnit.equal(attending(), 'yes', 'now it is yes'); + QUnit.equal(yes.checked, true, 'yes is checked'); + QUnit.equal(no.checked, false, 'no is unchecked'); + }); + QUnit.test('works without ~', function () { + var template = stache(''); + var attending = compute('yes'); + var yes = template({ attending: attending }).firstChild, no = yes.nextSibling; + QUnit.equal(yes.checked, true, 'initially a yes'); + QUnit.equal(no.checked, false, 'initially unchecked'); + attending('no'); + QUnit.equal(yes.checked, false, 'now not checked'); + QUnit.equal(no.checked, true, 'now checked'); + yes.checked = true; + domEvents.dispatch(yes, 'change'); + QUnit.equal(attending(), 'yes', 'now it is yes'); + QUnit.equal(yes.checked, true, 'yes is checked'); + QUnit.equal(no.checked, false, 'no is unchecked'); + }); + QUnit.test('Allows one-way binding when passed a non-compute as the first argument', function () { + var template = stache(''); + var attending = compute(false); + var input = template({ attending: attending }).firstChild; + QUnit.equal(input.checked, false, 'initially false'); + attending(true); + QUnit.equal(input.checked, true, 'can be changed to true'); + input.checked = false; + QUnit.equal(attending(), true, 'does not change compute'); + }); + QUnit.test('Allow multiple expressions to be passed in', function () { + var template = stache(''); + var foo = compute(true); + var bar = compute(false); + var input = template({ + foo: foo, + bar: bar + }).firstChild; + QUnit.equal(input.checked, false, 'initially unchecked'); + bar(true); + QUnit.equal(input.checked, true, 'now checked'); + foo(false); + bar(false); + QUnit.equal(input.checked, false, 'now unchecked'); + input.checked = true; + domEvents.dispatch(input, 'change'); + QUnit.equal(foo(), true, 'computed foo value is true'); + QUnit.equal(bar(), true, 'computed bar value is true'); + }); + QUnit.test('Allow multiple expressions to be passed in without ~', function () { + var template = stache(''); + var foo = compute(true); + var bar = compute(false); + var input = template({ + foo: foo, + bar: bar + }).firstChild; + QUnit.equal(input.checked, false, 'initially unchecked'); + bar(true); + QUnit.equal(input.checked, true, 'now checked'); + foo(false); + bar(false); + QUnit.equal(input.checked, false, 'now unchecked'); + input.checked = true; + domEvents.dispatch(input, 'change'); + QUnit.equal(foo(), true, 'computed foo value is true'); + QUnit.equal(bar(), true, 'computed bar value is true'); + }); + QUnit.test('Allow non static values', function () { + var template = stache('{{# each(foo) }}{{/ each}}'); + var foo = new DefineList(['foobar']); + var bar = new DefineMap({ value: 'zed' }); + var input = template({ + foo: foo, + bar: bar + }).querySelector('input'); + QUnit.equal(input.checked, false, 'initially unchecked'); + bar.value = 'foobar'; + QUnit.equal(input.checked, true, 'now checked'); + }); +}); +/*can-stache-converters@4.2.5#test/test*/ +define('can-stache-converters@4.2.5#test/test', [ + 'require', + 'exports', + 'module', + './boolean-to-inList_test', + './index-to-selected_test', + './selected-to-index_test', + './string-to-any_test', + './not_test', + './either-or_test', + './equal_test' +], function (require, exports, module) { + require('./boolean-to-inList_test'); + require('./index-to-selected_test'); + require('./selected-to-index_test'); + require('./string-to-any_test'); + require('./not_test'); + require('./either-or_test'); + require('./equal_test'); +}); +/*can-compute@4.1.0#proto-compute_test*/ +define('can-compute@4.1.0#proto-compute_test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-compute/proto-compute', + 'can-queues', + 'can-symbol', + 'can-reflect' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var Compute = require('can-compute/proto-compute'); + var queues = require('can-queues'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + QUnit.module('can/Compute'); + test('single value compute', function () { + expect(2); + var num = new Compute(1); + num.bind('change', function (ev, newVal, oldVal) { + equal(newVal, 2, 'newVal'); + equal(oldVal, 1, 'oldVal'); + }); + num.set(2); + }); + test('inner computes values are not bound to', function () { + var num = new Compute(1); + var outer = new Compute(function () { + var inner = new Compute(function () { + return num.get() + 1; + }); + return 2 * inner.get(); + }); + var handler = function () { + }; + outer.bind('change', handler); + stop(); + setTimeout(function () { + var handlers = num[canSymbol.for('can.meta')].handlers; + equal(handlers.get([]).length, 1, 'compute only bound to once'); + start(); + }, 50); + }); + test('compute.truthy', function () { + var result = 0; + var num = new Compute(3); + var truthy = Compute.truthy(num); + var tester = new Compute(function () { + if (truthy.get()) { + return ++result; + } else { + return ++result; + } + }); + tester.bind('change', function (ev, newVal, oldVal) { + if (num.get() === 0) { + equal(newVal, 2, '2 is the new val'); + } else if (num.get() === -1) { + equal(newVal, 3, '3 is the new val'); + } else { + ok(false, 'change should not be called'); + } + }); + equal(tester.get(), 1, 'on bind, we call tester once'); + num.set(2); + num.set(1); + num.set(0); + num.set(-1); + }); + test('a binding compute does not double read', function () { + var sourceAge = 30, timesComputeIsCalled = 0; + var age = new Compute(function (newVal) { + timesComputeIsCalled++; + if (timesComputeIsCalled === 1) { + ok(true, 'reading age to get value'); + } else if (timesComputeIsCalled === 2) { + equal(newVal, 31, 'the second time should be an update'); + } else if (timesComputeIsCalled === 3) { + ok(true, 'called after set to get the value'); + } else { + ok(false, 'You\'ve called the callback ' + timesComputeIsCalled + ' times'); + } + if (arguments.length) { + sourceAge = newVal; + } else { + return sourceAge; + } + }); + var info = new Compute(function () { + return 'I am ' + age.get(); + }); + var k = function () { + }; + info.bind('change', k); + equal(info.get(), 'I am 30'); + age.set(31); + equal(info.get(), 'I am 31'); + }); + test('cloning a setter compute (#547)', function () { + var name = new Compute('', function (newVal) { + return this.txt + newVal; + }); + var cloned = name.clone({ txt: '.' }); + cloned.set('-'); + equal(cloned.get(), '.-'); + }); + test('compute updated method uses get and old value (#732)', function () { + expect(9); + var input = { value: 1 }; + var value = new Compute('', { + get: function () { + return input.value; + }, + set: function (newVal) { + input.value = newVal; + }, + on: function (update) { + input.onchange = update; + }, + off: function () { + delete input.onchange; + } + }); + equal(value.get(), 1, 'original value'); + ok(!input.onchange, 'nothing bound'); + value.set(2); + equal(value.get(), 2, 'updated value'); + equal(input.value, 2, 'updated input.value'); + value.bind('change', function (ev, newVal, oldVal) { + equal(newVal, 3, 'newVal'); + equal(oldVal, 2, 'oldVal'); + value.unbind('change', this.Constructor); + }); + ok(input.onchange, 'binding to onchange'); + input.value = 3; + input.onchange({}); + ok(!input.onchange, 'removed binding'); + equal(value.get(), 3); + }); + test('a compute updated by source changes within a batch is part of that batch', function () { + var computeA = new Compute('a'); + var computeB = new Compute('b'); + var combined1 = new Compute(function () { + return computeA.get() + ' ' + computeB.get(); + }); + var combined2 = new Compute(function () { + return computeA.get() + ' ' + computeB.get(); + }); + var combo = new Compute(function () { + return combined1.get() + ' ' + combined2.get(); + }); + var callbacks = 0; + combo.bind('change', function () { + if (callbacks === 0) { + ok(true, 'called change once'); + } else { + ok(false, 'called change multiple times'); + } + callbacks++; + }); + queues.batch.start(); + computeA.set('A'); + computeB.set('B'); + queues.batch.stop(); + }); + test('Compute.async can be like a normal getter', function () { + var first = new Compute('Justin'), last = new Compute('Meyer'), fullName = Compute.async('', function () { + return first.get() + ' ' + last.get(); + }); + equal(fullName.get(), 'Justin Meyer'); + }); + test('Compute.async operate on single value', function () { + var a = new Compute(1); + var b = new Compute(2); + var obj = Compute.async({}, function (curVal) { + if (a.get()) { + curVal.a = a.get(); + } else { + delete curVal.a; + } + if (b.get()) { + curVal.b = b.get(); + } else { + delete curVal.b; + } + return curVal; + }); + obj.bind('change', function () { + }); + deepEqual(obj.get(), { + a: 1, + b: 2 + }, 'object has all properties'); + a.set(0); + deepEqual(obj.get(), { b: 2 }, 'removed a'); + b.set(0); + deepEqual(obj.get(), {}, 'removed b'); + }); + test('Compute.async async changing value', function () { + var a = new Compute(1); + var b = new Compute(2); + var async = Compute.async(undefined, function (curVal, setVal) { + if (a.get()) { + setTimeout(function () { + setVal('a'); + }, 10); + } else if (b.get()) { + setTimeout(function () { + setVal('b'); + }, 10); + } else { + return null; + } + }); + var changeArgs = [ + { + newVal: 'a', + oldVal: undefined, + run: function () { + a.set(0); + } + }, + { + newVal: 'b', + oldVal: 'a', + run: function () { + b.set(0); + } + }, + { + newVal: null, + oldVal: 'b', + run: function () { + start(); + } + } + ], changeNum = 0; + stop(); + async.bind('change', function (ev, newVal, oldVal) { + var data = changeArgs[changeNum++]; + equal(newVal, data.newVal, 'newVal is correct'); + equal(oldVal, data.oldVal, 'oldVal is correct'); + setTimeout(data.run, 10); + }); + }); + test('Compute.async read without binding', function () { + var source = new Compute(1); + var async = Compute.async([], function (curVal, setVal) { + curVal.push(source.get()); + return curVal; + }); + ok(async.get(), 'calling async worked'); + }); + test('Compute.async set uses last set or initial value', function () { + var add = new Compute(1); + var fnCount = 0; + var async = Compute.async(10, function (curVal) { + switch (fnCount++) { + case 0: + equal(curVal, 10); + break; + case 1: + equal(curVal, 20); + break; + case 2: + equal(curVal, 30, 'on bind'); + break; + case 3: + equal(curVal, 30, 'on bind'); + break; + } + return curVal + add.get(); + }); + equal(async.get(), 11, 'initial value'); + async.set(20); + async.bind('change', function () { + }); + async.set(20); + async.set(30); + }); + test('Change propagation in a batch with late bindings (#2412)', function () { + var rootA = new Compute('a'); + var rootB = new Compute('b'); + var childA = new Compute(function () { + return 'childA' + rootA.get(); + }); + var grandChild = new Compute(function () { + var b = rootB.get(); + if (b === 'b') { + return 'grandChild->b'; + } + var a = childA.get(); + return 'grandChild->' + a; + }); + childA.bind('change', function (ev, newVal, oldVal) { + }); + grandChild.bind('change', function (ev, newVal, oldVal) { + equal(newVal, 'grandChild->childAA'); + }); + queues.batch.start(); + rootA.set('A'); + rootB.set('B'); + queues.batch.stop(); + }); + if (Compute.prototype.trace) { + test('trace', function () { + var rootA = new Compute('a'); + var rootB = new Compute('b'); + var childA = new Compute(function () { + return 'childA' + rootA.get(); + }); + var fn = function () { + var b = rootB.get(); + if (b === 'b') { + return 'grandChild->b'; + } + var a = childA.get(); + return 'grandChild->' + a; + }; + var grandChild = new Compute(fn); + childA.bind('change', function (ev, newVal, oldVal) { + }); + grandChild.bind('change', function (ev, newVal, oldVal) { + equal(newVal, 'grandChild->childAA'); + }); + var out = grandChild.trace(); + equal(out.definition, fn, 'got the right function'); + equal(out.computeValue, 'grandChild->b'); + grandChild.log(); + queues.batch.start(); + rootA.set('A'); + rootB.set('B'); + queues.batch.stop(); + grandChild.log(); + }); + } + test('works with can-reflect', 5, function () { + var c = new Compute(0); + QUnit.equal(canReflect.getValue(c), 0, 'unbound value'); + QUnit.ok(canReflect.isValueLike(c), 'isValueLike is true'); + QUnit.ok(!canReflect.valueHasDependencies(c), 'valueHasDependencies -- false'); + var d = new Compute(function () { + return c.get(); + }); + d.on('change', function () { + }); + QUnit.ok(canReflect.valueHasDependencies(d), 'valueHasDependencies -- true'); + c.set(1); + QUnit.equal(canReflect.getValue(d), 1, 'bound value'); + c.set(2); + }); + QUnit.test('can-reflect setValue', function () { + var a = new Compute('a'); + canReflect.setValue(a, 'A'); + QUnit.equal(a.get(), 'A', 'compute'); + }); + QUnit.test('registered symbols', function () { + var a = new Compute('a'); + ok(a[canSymbol.for('can.isValueLike')], 'can.isValueLike'); + equal(a[canSymbol.for('can.getValue')](), 'a', 'can.getValue'); + a[canSymbol.for('can.setValue')]('b'); + equal(a.get(), 'b', 'can.setValue'); + function handler(val) { + equal(val, 'c', 'can.onValue'); + } + a[canSymbol.for('can.onValue')](handler); + a.set('c'); + a[canSymbol.for('can.offValue')](handler); + a.set('d'); + }); + QUnit.test('canReflect.onValue should get the previous value', function (assert) { + var a = new Compute('a'); + var done = assert.async(); + canReflect.onValue(a, function (newVal, oldVal) { + assert.equal(newVal, 'b'); + assert.equal(oldVal, 'a'); + done(); + }); + a.set('b'); + }); +}); +/*can-compute@4.1.0#can-compute_test*/ +define('can-compute@4.1.0#can-compute_test', [ + 'require', + 'exports', + 'module', + './proto-compute_test', + 'can-compute', + 'steal-qunit', + 'can-observation-recorder', + 'can-symbol', + 'can-reflect', + 'can-event-queue/map/map', + 'can-queues', + 'can-dom-events' +], function (require, exports, module) { + require('./proto-compute_test'); + var compute = require('can-compute'); + var QUnit = require('steal-qunit'); + var ObservationRecorder = require('can-observation-recorder'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + var eventQueue = require('can-event-queue/map/map'); + var queues = require('can-queues'); + var domEvents = require('can-dom-events'); + var metaSymbol = canSymbol.for('can.meta'); + var domDispatch = domEvents.dispatch; + QUnit.module('can/compute'); + test('single value compute', function () { + var num = compute(1); + num.on('change', function (ev, newVal, oldVal) { + equal(newVal, 2, 'newVal'); + equal(oldVal, 1, 'oldVal'); + }); + num(2); + }); + test('inner computes values are not bound to', function () { + var num = compute(1); + var outer = compute(function () { + var inner = compute(function () { + return num() + 1; + }); + return 2 * inner(); + }); + var handler = function () { + }; + outer.on('change', handler); + stop(); + setTimeout(function () { + equal(num.computeInstance[metaSymbol].handlers.get([]).length, 1, 'inner compute only bound once'); + equal(outer.computeInstance[metaSymbol].handlers.get([]).length, 1, 'outer compute only bound once'); + start(); + }, 50); + }); + test('compute.truthy', function () { + var result = 0; + var numValue; + var num = compute(numValue = 3); + var truthy = compute.truthy(num); + var tester = compute(function () { + if (truthy()) { + return ++result; + } else { + return ++result; + } + }); + tester.addEventListener('change', function (ev, newVal, oldVal) { + if (num() === 0) { + equal(newVal, 2, '2 is the new val'); + } else if (num() === -1) { + equal(newVal, 3, '3 is the new val'); + } else { + ok(false, 'change should not be called'); + } + }); + equal(tester(), 1, 'on bind, we call tester once'); + num(numValue = 2); + num(numValue = 1); + num(numValue = 0); + num(numValue = -1); + }); + test('a binding compute does not double read', function () { + var sourceAge = 30, timesComputeIsCalled = 0; + var age = compute(function (newVal) { + timesComputeIsCalled++; + if (timesComputeIsCalled === 1) { + ok(true, 'reading age to get value'); + } else if (timesComputeIsCalled === 2) { + equal(newVal, 31, 'the second time should be an update'); + } else if (timesComputeIsCalled === 3) { + ok(true, 'called after set to get the value'); + } else { + ok(false, 'You\'ve called the callback ' + timesComputeIsCalled + ' times'); + } + if (arguments.length) { + sourceAge = newVal; + } else { + return sourceAge; + } + }); + var info = compute(function () { + return 'I am ' + age(); + }); + var k = function () { + }; + info.bind('change', k); + equal(info(), 'I am 30'); + age(31); + equal(info(), 'I am 31'); + }); + test('cloning a setter compute (#547)', function () { + var name = compute('', function (newVal) { + return this.txt + newVal; + }); + var cloned = name.clone({ txt: '.' }); + cloned('-'); + equal(cloned(), '.-'); + }); + test('compute updated method uses get and old value (#732)', function () { + expect(9); + var input = { value: 1 }; + var value = compute('', { + get: function () { + return input.value; + }, + set: function (newVal) { + input.value = newVal; + }, + on: function (update) { + input.onchange = update; + }, + off: function () { + delete input.onchange; + } + }); + equal(value(), 1, 'original value'); + ok(!input.onchange, 'nothing bound'); + value(2); + equal(value(), 2, 'updated value'); + equal(input.value, 2, 'updated input.value'); + function handler(ev, newVal, oldVal) { + equal(newVal, 3, 'newVal'); + equal(oldVal, 2, 'oldVal'); + value.unbind('change', handler); + } + value.bind('change', handler); + ok(input.onchange, 'binding to onchange'); + input.value = 3; + input.onchange({}); + ok(!input.onchange, 'removed binding'); + equal(value(), 3); + }); + test('a compute updated by source changes within a batch is part of that batch', function () { + var computeA = compute('a'); + var computeB = compute('b'); + var combined1 = compute(function combined1() { + return computeA() + ' ' + computeB(); + }); + var combined2 = compute(function combined2() { + return computeA() + ' ' + computeB(); + }); + var combo = compute(function combo() { + return combined1() + ' ' + combined2(); + }); + var callbacks = 0; + combo.bind('change', function () { + if (callbacks === 0) { + ok(true, 'called change once'); + } else { + ok(false, 'called change multiple times'); + } + callbacks++; + }); + queues.batch.start(); + computeA('A'); + computeB('B'); + queues.batch.stop(); + }); + test('compute.async can be like a normal getter', function () { + var first = compute('Justin'), last = compute('Meyer'), fullName = compute.async('', function () { + return first() + ' ' + last(); + }); + equal(fullName(), 'Justin Meyer'); + }); + test('compute.async operate on single value', function () { + var a = compute(1); + var b = compute(2); + var obj = compute.async({}, function (curVal) { + if (a()) { + curVal.a = a(); + } else { + delete curVal.a; + } + if (b()) { + curVal.b = b(); + } else { + delete curVal.b; + } + return curVal; + }); + obj.bind('change', function () { + }); + deepEqual(obj(), { + a: 1, + b: 2 + }, 'object has all properties'); + a(0); + deepEqual(obj(), { b: 2 }, 'removed a'); + b(0); + deepEqual(obj(), {}, 'removed b'); + }); + test('compute.async async changing value', function () { + var a = compute(1); + var b = compute(2); + var async = compute.async(undefined, function (curVal, setVal) { + if (a()) { + setTimeout(function () { + setVal('a'); + }, 10); + } else if (b()) { + setTimeout(function () { + setVal('b'); + }, 10); + } else { + return null; + } + }); + var changeArgs = [ + { + newVal: 'a', + oldVal: undefined, + run: function () { + a(0); + } + }, + { + newVal: 'b', + oldVal: 'a', + run: function () { + b(0); + } + }, + { + newVal: null, + oldVal: 'b', + run: function () { + start(); + } + } + ], changeNum = 0; + stop(); + async.bind('change', function (ev, newVal, oldVal) { + var data = changeArgs[changeNum++]; + equal(newVal, data.newVal, 'newVal is correct'); + equal(oldVal, data.oldVal, 'oldVal is correct'); + setTimeout(data.run, 10); + }); + }); + test('compute.async read without binding', function () { + var source = compute(1); + var async = compute.async([], function (curVal, setVal) { + curVal.push(source()); + return curVal; + }); + ok(async(), 'calling async worked'); + }); + test('bug with nested computes and batch ordering (#1519)', function () { + var root = compute('a'); + var isA = compute(function () { + return root() === 'a'; + }); + var isB = compute(function () { + return root() === 'b'; + }); + var combined = compute(function () { + var valA = isA(), valB = isB(); + return valA || valB; + }); + equal(combined(), true); + combined.bind('change', function () { + }); + queues.batch.start(); + root('b'); + queues.batch.stop(); + equal(combined(), true); + }); + test('compute change handler context is set to the function not compute', function () { + var comp = compute(null); + comp.bind('change', function () { + equal(typeof this, 'function'); + }); + comp('test'); + }); + test('Calling .unbind() on un-bound compute does not throw an error', function () { + var count = compute(0); + count.unbind('change'); + ok(true, 'No error was thrown'); + }); + test('dependent computes update in the right order (2093)', function () { + var root = compute('a'), childB = compute(function () { + return root(); + }), combine = compute(function () { + return root() + childB(); + }); + combine.bind('change', function (ev, newVal) { + equal(newVal, 'bb', 'concat changed'); + }); + root('b'); + }); + test('dependent computes update in the right order with a batch (#2093)', function () { + var root = compute('a'), child = compute(function () { + return root(); + }), child2 = compute(function () { + return root(); + }), grandChild = compute(function () { + return child(); + }), combine = compute(function () { + return child2() + grandChild(); + }); + combine.bind('change', function (ev, newVal) { + equal(newVal, 'bb', 'concat changed'); + }); + queues.batch.start(); + root('b'); + queues.batch.stop(); + }); + test('bug with nested computes and batch ordering (#1519)', function () { + var root = compute('a'); + var isA = compute(function () { + return root() === 'a'; + }); + var isB = compute(function () { + return root() === 'b'; + }); + var combined = compute(function () { + var valA = isA(), valB = isB(); + return valA || valB; + }); + equal(combined(), true); + combined.bind('change', function () { + }); + queues.batch.start(); + root('b'); + queues.batch.stop(); + equal(combined(), true); + }); + test('binding, unbinding, and rebinding works after a timeout (#2095)', function () { + var root = compute(1), derived = compute(function () { + return root(); + }); + var change = function () { + }; + derived.bind('change', change); + derived.unbind('change', change); + stop(); + setTimeout(function () { + derived.bind('change', function (ev, newVal, oldVal) { + equal(newVal, 2, 'updated'); + start(); + }); + root(2); + }, 10); + }); + test('ObservationRecorder.isRecording observes doesn\'t understand ObservationRecorder.ignore (#2099)', function () { + expect(0); + var c = compute(1); + c.computeInstance.bind = function () { + ok(false); + }; + var outer = compute(function () { + ObservationRecorder.ignore(function () { + c(); + })(); + }); + outer.bind('change', function () { + }); + }); + test('handles missing update order items (#2121)', function () { + var root1 = compute('root1'), child1 = compute(function () { + return root1(); + }), root2 = compute('root2'), child2 = compute(function () { + return root2(); + }), gc2 = compute(function () { + return child2(); + }), res = compute(function () { + return child1() + gc2(); + }); + res.bind('change', function (ev, newVal) { + equal(newVal, 'ROOT1root2'); + }); + queues.batch.start(); + root1('ROOT1'); + queues.batch.stop(); + }); + test('compute should not fire event when NaN is set multiple times #2128', function () { + var c = compute(NaN); + compute.bind('change', function () { + ok(false, 'change event should not be fired'); + }); + ok(isNaN(c())); + c(NaN); + }); + test('eventQueue.afterPreviousEvents firing too late (#2198)', function () { + var compute1 = compute('a'), compute2 = compute('b'); + var derived = compute(function () { + return compute1().toUpperCase(); + }); + derived.bind('change', function () { + var afterPrevious = false; + compute2.bind('change', function () { + ok(afterPrevious, 'after previous should have fired so we would respond to this event'); + }); + queues.batch.start(); + queues.batch.stop(); + eventQueue.afterPreviousEvents(function () { + afterPrevious = true; + }); + compute2('c'); + }); + queues.batch.start(); + compute1('x'); + queues.batch.stop(); + }); + test('Async getter causes infinite loop (#28)', function () { + var changeCount = 0; + var idCompute = compute(1); + stop(); + var comp = compute.async(undefined, function (last, resolve) { + var id = idCompute(); + setTimeout(function () { + resolve(changeCount + '|' + id); + }, 1); + resolve(changeCount + '|' + id); + }, null); + comp.bind('change', function (ev, newVal) { + changeCount++; + comp(); + }); + setTimeout(function () { + idCompute(2); + }, 50); + var checkChangeCount = function () { + if (changeCount === 4) { + equal(changeCount, 4); + start(); + } else { + setTimeout(checkChangeCount, 10); + } + }; + checkChangeCount(); + }); + test('Listening to input change', function () { + var input = document.createElement('input'); + var comp = compute(input, 'value', 'input'); + comp.on('change', function () { + ok(true, 'it changed'); + }); + input.value = 'foo'; + domDispatch(input, 'input'); + }); + test('Setting an input to change', function () { + var input = document.createElement('input'); + var comp = compute(input, 'value', 'input'); + comp('foo'); + ok(input.value === 'foo'); + }); + test('compute.truthy with functions (canjs/can-stache#172)', function () { + var func = compute(function () { + return function () { + ok(false, 'should not be run'); + }; + }); + var truthy = compute.truthy(func); + equal(truthy(), true); + }); + test('works with can-reflect', 5, function () { + var c = compute(0); + QUnit.equal(canReflect.getValue(c), 0, 'unbound value'); + var handler = function (newValue) { + QUnit.equal(newValue, 1, 'observed new value'); + canReflect.offValue(c, handler); + }; + QUnit.ok(canReflect.isValueLike(c), 'isValueLike is true'); + canReflect.onValue(c, handler); + QUnit.equal(canReflect.valueHasDependencies(c), undefined, 'valueHasDependencies'); + c(1); + QUnit.equal(canReflect.getValue(c), 1, 'bound value'); + c(2); + }); + QUnit.test('can-reflect valueHasDependencies', function () { + var a = compute('a'); + var b = compute('b'); + var c = compute(function () { + return a() + b(); + }); + c.on('change', function () { + }); + QUnit.ok(canReflect.valueHasDependencies(c), 'valueHasDependencies'); + }); + QUnit.test('registered symbols', function () { + var a = compute('a'); + ok(a[canSymbol.for('can.isValueLike')], 'can.isValueLike'); + equal(a[canSymbol.for('can.getValue')](), 'a', 'can.getValue'); + a[canSymbol.for('can.setValue')]('b'); + equal(a(), 'b', 'can.setValue'); + function handler(val) { + equal(val, 'c', 'can.onValue'); + } + a[canSymbol.for('can.onValue')](handler); + a('c'); + a[canSymbol.for('can.offValue')](handler); + a('d'); + }); + QUnit.test('can-reflect setValue', function () { + var a = compute('a'); + canReflect.setValue(a, 'A'); + QUnit.equal(a(), 'A', 'compute'); + }); + QUnit.test('Calling .unbind() with no arguments should tear down all event handlers', function () { + var count = compute(0); + count.on('change', function () { + console.log('Count changed'); + }); + var handlers = count.computeInstance[canSymbol.for('can.meta')].handlers; + QUnit.equal(handlers.get(['change']).length, 1, 'Change event added'); + count.unbind(); + QUnit.equal(handlers.get(['change']).length, 0, 'All events for compute removed'); + }); + QUnit.test('.off() unbinds a given handler', function () { + var handler = function () { + }; + var c = compute('foo'); + c.on('change', handler); + var handlers = c.computeInstance[canSymbol.for('can.meta')].handlers; + QUnit.equal(handlers.get(['change']).length, 1, 'handler added'); + c.off('change', handler); + QUnit.equal(handlers.get(['change']).length, 0, 'hander removed'); + }); +}); +/*can-map@4.3.3#bubble*/ +define('can-map@4.3.3#bubble', [ + 'require', + 'exports', + 'module', + 'can-event-queue/map/map', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var canEvent = require('can-event-queue/map/map'); + var canReflect = require('can-reflect'); + var bubble = { + bind: function (parent, eventName) { + if (!parent.__inSetup) { + var bubbleEvents = bubble.events(parent, eventName), len = bubbleEvents.length, bubbleEvent; + if (!parent._bubbleBindings) { + parent._bubbleBindings = {}; + } + for (var i = 0; i < len; i++) { + bubbleEvent = bubbleEvents[i]; + if (!parent._bubbleBindings[bubbleEvent]) { + parent._bubbleBindings[bubbleEvent] = 1; + bubble.childrenOf(parent, bubbleEvent); + } else { + parent._bubbleBindings[bubbleEvent]++; + } + } + } + }, + unbind: function (parent, eventName) { + var bubbleEvents = bubble.events(parent, eventName), len = bubbleEvents.length, bubbleEvent; + for (var i = 0; i < len; i++) { + bubbleEvent = bubbleEvents[i]; + if (parent._bubbleBindings) { + parent._bubbleBindings[bubbleEvent]--; + } + if (parent._bubbleBindings && !parent._bubbleBindings[bubbleEvent]) { + delete parent._bubbleBindings[bubbleEvent]; + bubble.teardownChildrenFrom(parent, bubbleEvent); + if (canReflect.size(parent._bubbleBindings) === 0) { + delete parent._bubbleBindings; + } + } + } + }, + add: function (parent, child, prop) { + if (canReflect.isObservableLike(child) && canReflect.isMapLike(child) && parent._bubbleBindings) { + for (var eventName in parent._bubbleBindings) { + if (parent._bubbleBindings[eventName]) { + bubble.teardownFromParent(parent, child, eventName); + bubble.toParent(child, parent, prop, eventName); + } + } + } + }, + addMany: function (parent, children) { + for (var i = 0, len = children.length; i < len; i++) { + bubble.add(parent, children[i], i); + } + }, + remove: function (parent, child) { + if (canReflect.isObservableLike(child) && canReflect.isMapLike(child) && parent._bubbleBindings) { + for (var eventName in parent._bubbleBindings) { + if (parent._bubbleBindings[eventName]) { + bubble.teardownFromParent(parent, child, eventName); + } + } + } + }, + removeMany: function (parent, children) { + for (var i = 0, len = children.length; i < len; i++) { + bubble.remove(parent, children[i]); + } + }, + set: function (parent, prop, value, current) { + if (canReflect.isObservableLike(value) && canReflect.isMapLike(value)) { + bubble.add(parent, value, prop); + } + if (canReflect.isObservableLike(current) && canReflect.isMapLike(current)) { + bubble.remove(parent, current); + } + return value; + }, + events: function (map, boundEventName) { + return map.constructor._bubbleRule(boundEventName, map); + }, + toParent: function (child, parent, prop, eventName) { + canEvent.listenTo.call(parent, child, eventName, function () { + var args = canReflect.toArray(arguments), ev = args.shift(); + args[0] = (canReflect.isObservableLike(parent) && canReflect.isListLike(parent) ? parent.indexOf(child) : prop) + (args[0] ? '.' + args[0] : ''); + ev.triggeredNS = ev.triggeredNS || {}; + if (ev.triggeredNS[parent._cid]) { + return; + } + ev.triggeredNS[parent._cid] = true; + canEvent.dispatch.call(parent, ev, args); + if (eventName === 'change') { + canEvent.dispatch.call(parent, args[0], [ + args[2], + args[3] + ]); + } + }); + }, + childrenOf: function (parent, eventName) { + parent._each(function (child, prop) { + if (child && child.bind) { + bubble.toParent(child, parent, prop, eventName); + } + }); + }, + teardownFromParent: function (parent, child, eventName) { + if (child && child.unbind) { + canEvent.stopListening.call(parent, child, eventName); + } + }, + teardownChildrenFrom: function (parent, eventName) { + parent._each(function (child) { + bubble.teardownFromParent(parent, child, eventName); + }); + }, + isBubbling: function (parent, eventName) { + return parent._bubbleBindings && parent._bubbleBindings[eventName]; + } + }; + module.exports = bubble; +}); +/*can-map@4.3.3#map-helpers*/ +define('can-map@4.3.3#map-helpers', [ + 'require', + 'exports', + 'module', + 'can-cid', + 'can-assign', + 'can-reflect', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var CID = require('can-cid'); + var assign = require('can-assign'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var madeMap = null; + var teardownMap = function () { + for (var cid in madeMap) { + if (madeMap[cid].added) { + delete madeMap[cid].obj._cid; + } + } + madeMap = null; + }; + var mapHelpers = { + attrParts: function (attr, keepKey) { + if (keepKey) { + return [attr]; + } + return typeof attr === 'object' ? attr : ('' + attr).split('.'); + }, + canMakeObserve: function (obj) { + return obj && !canReflect.isPromise(obj) && (Array.isArray(obj) || canReflect.isPlainObject(obj)); + }, + reflectSerialize: function (unwrapped) { + this.forEach(function (val, name) { + if (this.___serialize) { + val = this.___serialize(name, val); + } else { + val = canReflect.serialize(val); + } + if (val !== undefined) { + unwrapped[name] = val; + } + }, this); + return unwrapped; + }, + reflectUnwrap: function (unwrapped) { + this.forEach(function (value, key) { + if (value !== undefined) { + unwrapped[key] = canReflect.unwrap(value); + } + }); + return unwrapped; + }, + removeSpecialKeys: function (map) { + if (map) { + [ + '_data', + 'constructor', + '_cid', + '__bindEvents' + ].forEach(function (key) { + delete map[key]; + }); + } + return map; + }, + serialize: function () { + var serializeMap = null; + return function (map, how, where) { + var cid = CID(map), firstSerialize = false; + if (!serializeMap) { + firstSerialize = true; + serializeMap = { + attr: {}, + serialize: {} + }; + } + serializeMap[how][cid] = where; + map.forEach(function (val, name) { + var result, isObservable = canReflect.isObservableLike(val), serialized = isObservable && serializeMap[how][CID(val)]; + if (serialized) { + result = serialized; + } else { + if (map['___' + how]) { + result = map['___' + how](name, val); + } else { + result = mapHelpers.getValue(map, name, val, how); + } + } + if (result !== undefined) { + where[name] = result; + } + }); + if (firstSerialize) { + serializeMap = null; + } + return where; + }; + }(), + getValue: function (map, name, val, how) { + if (how === 'attr') { + how = canSymbol.for('can.getValue'); + } + if (canReflect.isObservableLike(val) && val[how]) { + return val[how](); + } else { + return val; + } + }, + define: null, + addComputedAttr: function (map, attrName, compute) { + map._computedAttrs[attrName] = { + compute: compute, + count: 0, + handler: function (newVal, oldVal) { + map._triggerChange(attrName, 'set', newVal, oldVal); + } + }; + }, + addToMap: function addToMap(obj, instance) { + var teardown; + if (!madeMap) { + teardown = teardownMap; + madeMap = {}; + } + var hasCid = obj._cid; + var cid = CID(obj); + if (!madeMap[cid]) { + madeMap[cid] = { + obj: obj, + instance: instance, + added: !hasCid + }; + } + return teardown; + }, + getMapFromObject: function (obj) { + return madeMap && madeMap[obj._cid] && madeMap[obj._cid].instance; + }, + twoLevelDeepExtend: function (destination, source) { + for (var prop in source) { + destination[prop] = destination[prop] || {}; + assign(destination[prop], source[prop]); + } + } + }; + module.exports = exports = mapHelpers; +}); +/*can-types@1.4.0#can-types*/ +define('can-types@1.4.0#can-types', [ + 'require', + 'exports', + 'module', + 'can-namespace', + 'can-reflect', + 'can-symbol', + 'can-log/dev/dev' +], function (require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var dev = require('can-log/dev/dev'); + var types = { + isMapLike: function (obj) { + return canReflect.isObservableLike(obj) && canReflect.isMapLike(obj); + }, + isListLike: function (obj) { + return canReflect.isObservableLike(obj) && canReflect.isListLike(obj); + }, + isPromise: function (obj) { + return canReflect.isPromise(obj); + }, + isConstructor: function (func) { + return canReflect.isConstructorLike(func); + }, + isCallableForValue: function (obj) { + return obj && canReflect.isFunctionLike(obj) && !canReflect.isConstructorLike(obj); + }, + isCompute: function (obj) { + return obj && obj.isComputed; + }, + get iterator() { + return canSymbol.iterator || canSymbol.for('iterator'); + }, + DefaultMap: null, + DefaultList: null, + queueTask: function (task) { + var args = task[2] || []; + task[0].apply(task[1], args); + }, + wrapElement: function (element) { + return element; + }, + unwrapElement: function (element) { + return element; + } + }; + if (namespace.types) { + throw new Error('You can\'t have two versions of can-types, check your dependencies'); + } else { + module.exports = namespace.types = types; + } +}); +/*can-cid@1.3.0#helpers*/ +define('can-cid@1.3.0#helpers', function (require, exports, module) { + 'use strict'; + module.exports = { + each: function (obj, cb, context) { + for (var prop in obj) { + cb.call(context, obj[prop], prop); + } + return obj; + } + }; +}); +/*can-cid@1.3.0#set/set*/ +define('can-cid@1.3.0#set/set', [ + 'require', + 'exports', + 'module', + '../can-cid', + '../helpers' +], function (require, exports, module) { + 'use strict'; + var getCID = require('../can-cid').get; + var helpers = require('../helpers'); + var CIDSet; + if (typeof Set !== 'undefined') { + CIDSet = Set; + } else { + var CIDSet = function () { + this.values = {}; + }; + CIDSet.prototype.add = function (value) { + this.values[getCID(value)] = value; + }; + CIDSet.prototype['delete'] = function (key) { + var has = getCID(key) in this.values; + if (has) { + delete this.values[getCID(key)]; + } + return has; + }; + CIDSet.prototype.forEach = function (cb, thisArg) { + helpers.each(this.values, cb, thisArg); + }; + CIDSet.prototype.has = function (value) { + return getCID(value) in this.values; + }; + CIDSet.prototype.clear = function () { + return this.values = {}; + }; + Object.defineProperty(CIDSet.prototype, 'size', { + get: function () { + var size = 0; + helpers.each(this.values, function () { + size++; + }); + return size; + } + }); + } + module.exports = CIDSet; +}); +/*can-cid@1.3.0#map/map*/ +define('can-cid@1.3.0#map/map', [ + 'require', + 'exports', + 'module', + '../can-cid', + '../helpers' +], function (require, exports, module) { + 'use strict'; + var getCID = require('../can-cid').get; + var helpers = require('../helpers'); + var CIDMap; + if (typeof Map !== 'undefined') { + CIDMap = Map; + } else { + var CIDMap = function () { + this.values = {}; + }; + CIDMap.prototype.set = function (key, value) { + this.values[getCID(key)] = { + key: key, + value: value + }; + }; + CIDMap.prototype['delete'] = function (key) { + var has = getCID(key) in this.values; + if (has) { + delete this.values[getCID(key)]; + } + return has; + }; + CIDMap.prototype.forEach = function (cb, thisArg) { + helpers.each(this.values, function (pair) { + return cb.call(thisArg || this, pair.value, pair.key, this); + }, this); + }; + CIDMap.prototype.has = function (key) { + return getCID(key) in this.values; + }; + CIDMap.prototype.get = function (key) { + var obj = this.values[getCID(key)]; + return obj && obj.value; + }; + CIDMap.prototype.clear = function () { + return this.values = {}; + }; + Object.defineProperty(CIDMap.prototype, 'size', { + get: function () { + var size = 0; + helpers.each(this.values, function () { + size++; + }); + return size; + } + }); + } + module.exports = CIDMap; +}); +/*can-map@4.3.3#can-map*/ +define('can-map@4.3.3#can-map', [ + 'require', + 'exports', + 'module', + './bubble', + './map-helpers', + 'can-event-queue/map/map', + 'can-event-queue/type/type', + 'can-construct', + 'can-observation-recorder', + 'can-stache-key', + 'can-compute', + 'can-single-reference', + 'can-namespace', + 'can-log/dev/dev', + 'can-cid', + 'can-assign', + 'can-types', + 'can-reflect', + 'can-symbol', + 'can-cid/set/set', + 'can-cid/map/map', + 'can-queues' +], function (require, exports, module) { + 'use strict'; + var bubble = require('./bubble'); + var mapHelpers = require('./map-helpers'); + var canEvent = require('can-event-queue/map/map'); + var addTypeEvents = require('can-event-queue/type/type'); + var Construct = require('can-construct'); + var ObservationRecorder = require('can-observation-recorder'); + var ObserveReader = require('can-stache-key'); + var canCompute = require('can-compute'); + var singleReference = require('can-single-reference'); + var namespace = require('can-namespace'); + var dev = require('can-log/dev/dev'); + var CID = require('can-cid'); + var assign = require('can-assign'); + var types = require('can-types'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var CIDSet = require('can-cid/set/set'); + var CIDMap = require('can-cid/map/map'); + var canQueues = require('can-queues'); + var unobservable = { 'constructor': true }; + var hasOwnProperty = {}.hasOwnProperty; + var Map = Construct.extend({ + setup: function (baseMap) { + Construct.setup.apply(this, arguments); + this._computedPropertyNames = []; + if (Map) { + addTypeEvents(this); + this[canSymbol.for('can.defineInstanceKey')] = function (prop, definition) { + if (definition.value !== undefined) { + this.defaults[prop] = definition.value; + } + if (definition.enumerable === false) { + this.enumerable[prop] = false; + } + }; + if (!this.defaults) { + this.defaults = {}; + } + if (!this.enumerable) { + this.enumerable = {}; + } + for (var prop in this.prototype) { + if (prop !== 'define' && prop !== 'constructor' && (typeof this.prototype[prop] !== 'function' || this.prototype[prop].prototype instanceof Construct)) { + this.defaults[prop] = this.prototype[prop]; + } else if (canReflect.isObservableLike(this.prototype[prop])) { + this._computedPropertyNames.push(prop); + } + } + if (mapHelpers.define) { + mapHelpers.define(this, baseMap.prototype.define); + } + } + }, + shortName: 'Map', + _bubbleRule: function (eventName) { + return eventName === 'change' || eventName.indexOf('.') >= 0 ? ['change'] : []; + }, + addEventListener: canEvent.addEventListener, + removeEventListener: canEvent.removeEventListener, + keys: function (map) { + return canReflect.getOwnEnumerableKeys(map); + } + }, { + setup: function (obj) { + if (canReflect.isObservableLike(obj) && typeof obj.serialize === 'function') { + obj = obj.serialize(); + } + this._data = Object.create(null); + CID(this, '.map'); + this._setupComputedProperties(); + var teardownMapping = obj && mapHelpers.addToMap(obj, this); + var defaultValues = this._setupDefaults(obj); + var data = assign(canReflect.assignDeep({}, defaultValues), obj); + this.attr(data); + if (teardownMapping) { + teardownMapping(); + } + }, + _setupComputedProperties: function () { + this._computedAttrs = Object.create(null); + var computes = this.constructor._computedPropertyNames; + for (var i = 0, len = computes.length; i < len; i++) { + var attrName = computes[i]; + mapHelpers.addComputedAttr(this, attrName, this[attrName]); + } + }, + _setupDefaults: function () { + return this.constructor.defaults || {}; + }, + attr: function (attr, val) { + var type = typeof attr; + if (attr === undefined) { + return this._getAttrs(); + } else if (type !== 'string' && type !== 'number') { + return this._setAttrs(attr, val); + } else if (arguments.length === 1) { + return this._get(attr); + } else { + this._set(attr + '', val); + return this; + } + }, + _get: function (attr) { + attr = attr + ''; + var dotIndex = attr.indexOf('.'); + if (dotIndex >= 0) { + var value = this.___get(attr); + if (value !== undefined) { + ObservationRecorder.add(this, attr); + return value; + } + var first = attr.substr(0, dotIndex), second = attr.substr(dotIndex + 1); + var current = this.__get(first); + return current && canReflect.getKeyValue(current, second); + } else { + return this.__get(attr); + } + }, + __get: function (attr) { + if (!unobservable[attr] && !this._computedAttrs[attr]) { + ObservationRecorder.add(this, attr); + } + return this.___get(attr); + }, + ___get: function (attr) { + if (attr !== undefined) { + var computedAttr = this._computedAttrs[attr]; + if (computedAttr) { + return canReflect.getValue(computedAttr.compute); + } else { + return hasOwnProperty.call(this._data, attr) ? this._data[attr] : undefined; + } + } else { + return this._data; + } + }, + _set: function (attr, value, keepKey) { + attr = attr + ''; + var dotIndex = attr.indexOf('.'), current; + if (dotIndex >= 0 && !keepKey) { + var first = attr.substr(0, dotIndex), second = attr.substr(dotIndex + 1); + current = this.__inSetup ? undefined : this.___get(first); + if (canReflect.isMapLike(current)) { + canReflect.setKeyValue(current, second, value); + } else { + current = this.__inSetup ? undefined : this.___get(attr); + if (this.__convert) { + value = this.__convert(attr, value); + } + this.__set(attr, this.__type(value, attr), current); + } + } else { + current = this.__inSetup ? undefined : this.___get(attr); + if (this.__convert) { + value = this.__convert(attr, value); + } + this.__set(attr, this.__type(value, attr), current); + } + }, + __type: function (value, prop) { + if (typeof value === 'object' && !canReflect.isObservableLike(value) && mapHelpers.canMakeObserve(value) && !canReflect.isListLike(value)) { + var cached = mapHelpers.getMapFromObject(value); + if (cached) { + return cached; + } + var MapConstructor = this.constructor.Map || Map; + return new MapConstructor(value); + } + return value; + }, + __set: function (prop, value, current) { + if (value !== current || !Object.prototype.hasOwnProperty.call(this._data, prop)) { + var computedAttr = this._computedAttrs[prop]; + var changeType = computedAttr || current !== undefined || hasOwnProperty.call(this.___get(), prop) ? 'set' : 'add'; + this.___set(prop, typeof value === 'object' ? bubble.set(this, prop, value, current) : value); + if (!computedAttr || !computedAttr.count) { + this._triggerChange(prop, changeType, value, current); + } + if (typeof current === 'object') { + bubble.teardownFromParent(this, current); + } + } + }, + ___set: function (prop, val) { + var computedAttr = this._computedAttrs[prop]; + if (computedAttr) { + canReflect.setValue(computedAttr.compute, val); + } else { + this._data[prop] = val; + } + if (typeof this.constructor.prototype[prop] !== 'function' && !computedAttr) { + this[prop] = val; + } + }, + removeAttr: function (attr) { + return this._remove(attr); + }, + _remove: function (attr) { + var parts = mapHelpers.attrParts(attr), prop = parts.shift(), current = this.___get(prop); + if (parts.length && current) { + return canReflect.deleteKeyValue(current, parts.join('.')); + } else { + if (typeof attr === 'string' && !!~attr.indexOf('.')) { + prop = attr; + } + this.__remove(prop, current); + return current; + } + }, + __remove: function (prop, current) { + if (prop in this._data) { + this.___remove(prop); + this._triggerChange(prop, 'remove', undefined, current); + } + }, + ___remove: function (prop) { + delete this._data[prop]; + if (!(prop in this.constructor.prototype)) { + delete this[prop]; + } + }, + ___serialize: function (name, val) { + if (this._legacyAttrBehavior) { + return mapHelpers.getValue(this, name, val, 'serialize'); + } else { + return canReflect.serialize(val, CIDMap); + } + }, + _getAttrs: function () { + if (this._legacyAttrBehavior) { + return mapHelpers.serialize(this, 'attr', {}); + } else { + return canReflect.unwrap(this, CIDMap); + } + }, + _setAttrs: function (props, remove) { + if (this._legacyAttrBehavior) { + return this.__setAttrs(props, remove); + } + if (remove === true || remove === 'true') { + this[canSymbol.for('can.updateDeep')](props); + } else { + this[canSymbol.for('can.assignDeep')](props); + } + return this; + }, + __setAttrs: function (props, remove) { + props = assign({}, props); + var prop, self = this, newVal; + canQueues.batch.start(); + this._each(function (curVal, prop) { + if (prop === '_cid') { + return; + } + newVal = props[prop]; + if (newVal === undefined) { + if (remove) { + self.removeAttr(prop); + } + return; + } + if (self.__convert) { + newVal = self.__convert(prop, newVal); + } + if (types.isMapLike(curVal) && mapHelpers.canMakeObserve(newVal)) { + if (remove === true) { + canReflect.updateDeep(curVal, newVal); + } else { + canReflect.assignDeep(curVal, newVal); + } + } else if (curVal !== newVal) { + self.__set(prop, self.__type(newVal, prop), curVal); + } + delete props[prop]; + }); + for (prop in props) { + if (prop !== '_cid') { + newVal = props[prop]; + this._set(prop, newVal, true); + } + } + canQueues.batch.stop(); + return this; + }, + serialize: function () { + return canReflect.serialize(this, CIDMap); + }, + _triggerChange: function (attr, how, newVal, oldVal, batchNum) { + canQueues.batch.start(); + if (bubble.isBubbling(this, 'change')) { + canEvent.dispatch.call(this, { + type: 'change', + target: this, + batchNum: batchNum + }, [ + attr, + how, + newVal, + oldVal + ]); + } + canEvent.dispatch.call(this, { + type: attr, + target: this, + batchNum: batchNum, + patches: [{ + type: 'set', + key: attr, + value: newVal + }] + }, [ + newVal, + oldVal + ]); + if (how === 'remove' || how === 'add') { + canEvent.dispatch.call(this, { + type: '__keys', + target: this, + batchNum: batchNum + }); + } + canQueues.batch.stop(); + }, + compute: function (prop) { + if (typeof this.constructor.prototype[prop] === 'function') { + return canCompute(this[prop], this); + } else { + var reads = ObserveReader.reads(prop); + var last = reads.length - 1; + return canCompute(function (newVal) { + if (arguments.length) { + ObserveReader.write(this, reads[last].key, newVal, {}); + } else { + return ObserveReader.get(this, prop); + } + }, this); + } + }, + forEach: function (callback, context) { + var key, item; + var keys = canReflect.getOwnEnumerableKeys(this); + for (var i = 0, len = keys.length; i < len; i++) { + key = keys[i]; + item = this.attr(key); + if (callback.call(context || item, item, key, this) === false) { + break; + } + } + return this; + }, + _each: function (callback) { + var data = this.___get(); + for (var prop in data) { + if (hasOwnProperty.call(data, prop)) { + callback(data[prop], prop); + } + } + }, + dispatch: canEvent.dispatch + }); + canEvent(Map.prototype); + Map.prototype.addEventListener = function (eventName, handler) { + var computedBinding = this._computedAttrs && this._computedAttrs[eventName]; + if (computedBinding && computedBinding.compute) { + if (!computedBinding.count) { + computedBinding.count = 1; + canReflect.onValue(computedBinding.compute, computedBinding.handler, 'notify'); + } else { + computedBinding.count++; + } + } + bubble.bind(this, eventName); + return canEvent.addEventListener.apply(this, arguments); + }; + Map.prototype.removeEventListener = function (eventName, handler) { + var computedBinding = this._computedAttrs && this._computedAttrs[eventName]; + if (computedBinding) { + if (computedBinding.count === 1) { + computedBinding.count = 0; + canReflect.offValue(computedBinding.compute, computedBinding.handler); + } else { + computedBinding.count--; + } + } + bubble.unbind(this, eventName); + return canEvent.removeEventListener.apply(this, arguments); + }; + Map.prototype.on = Map.prototype.bind = Map.prototype.addEventListener; + Map.prototype.off = Map.prototype.unbind = Map.prototype.removeEventListener; + Map.on = Map.bind = Map.addEventListener; + Map.off = Map.unbind = Map.removeEventListener; + canReflect.assignSymbols(Map.prototype, { + 'can.isMapLike': true, + 'can.isListLike': false, + 'can.isValueLike': false, + 'can.getKeyValue': Map.prototype._get, + 'can.setKeyValue': Map.prototype._set, + 'can.deleteKeyValue': Map.prototype._remove, + 'can.getOwnEnumerableKeys': function () { + if (!this.__inSetup) { + ObservationRecorder.add(this, '__keys'); + } + var enumerable = this.constructor.enumerable; + if (enumerable) { + return Object.keys(this._data).filter(function (key) { + return enumerable[key] !== false; + }, this); + } else { + return Object.keys(this._data); + } + }, + 'can.assignDeep': function (source) { + canQueues.batch.start(); + canReflect.assignDeepMap(this, mapHelpers.removeSpecialKeys(canReflect.assignMap({}, source))); + canQueues.batch.stop(); + }, + 'can.updateDeep': function (source) { + canQueues.batch.start(); + canReflect.updateDeepMap(this, mapHelpers.removeSpecialKeys(canReflect.assignMap({}, source))); + canQueues.batch.stop(); + }, + 'can.unwrap': mapHelpers.reflectUnwrap, + 'can.serialize': mapHelpers.reflectSerialize, + 'can.onKeyValue': function (key, handler, queue) { + var translationHandler = function (ev, newValue, oldValue) { + handler.call(this, newValue, oldValue); + }; + singleReference.set(handler, this, translationHandler, key); + this.addEventListener(key, translationHandler, queue); + }, + 'can.offKeyValue': function (key, handler, queue) { + this.removeEventListener(key, singleReference.getAndDelete(handler, this, key), queue); + }, + 'can.keyHasDependencies': function (key) { + return !!(this._computedAttrs && this._computedAttrs[key] && this._computedAttrs[key].compute); + }, + 'can.getKeyDependencies': function (key) { + var ret; + if (this._computedAttrs && this._computedAttrs[key] && this._computedAttrs[key].compute) { + ret = {}; + ret.valueDependencies = new CIDSet(); + ret.valueDependencies.add(this._computedAttrs[key].compute); + } + return ret; + } + }); + if (!types.DefaultMap) { + types.DefaultMap = Map; + } + module.exports = namespace.Map = Map; +}); +/*can-list@4.2.0#can-list*/ +define('can-list@4.2.0#can-list', [ + 'require', + 'exports', + 'module', + 'can-namespace', + 'can-map', + 'can-map/bubble', + 'can-map/map-helpers', + 'can-queues', + 'can-event-queue/map/map', + 'can-observation-recorder', + 'can-cid', + 'can-reflect', + 'can-assign', + 'can-types', + 'can-symbol', + 'can-cid/map/map' +], function (require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + var Map = require('can-map'); + var bubble = require('can-map/bubble'); + var mapHelpers = require('can-map/map-helpers'); + var queues = require('can-queues'); + var canEvent = require('can-event-queue/map/map'); + var ObservationRecorder = require('can-observation-recorder'); + var CID = require('can-cid'); + var canReflect = require('can-reflect'); + var assign = require('can-assign'); + var types = require('can-types'); + var canSymbol = require('can-symbol'); + var CIDMap = require('can-cid/map/map'); + var splice = [].splice, spliceRemovesProps = function () { + var obj = { + 0: 'a', + length: 1 + }; + splice.call(obj, 0, 1); + return !obj[0]; + }(); + var serializeNonTypes = function (MapType, arg, args) { + if (arg && arg.serialize && !(arg instanceof MapType)) { + args.push(new MapType(arg.serialize())); + } else { + args.push(arg); + } + }; + var List = Map.extend({ Map: Map }, { + setup: function (instances, options) { + this.length = 0; + CID(this, '.map'); + this._setupComputedProperties(); + instances = instances === undefined ? [] : canReflect.toArray(instances); + var teardownMapping; + if (canReflect.isPromise(instances)) { + this.replace(instances); + } else { + teardownMapping = instances.length && mapHelpers.addToMap(instances, this); + this.push.apply(this, instances); + } + if (teardownMapping) { + teardownMapping(); + } + assign(this, options); + }, + _triggerChange: function (attr, how, newVal, oldVal) { + queues.batch.start(); + var index = +attr, patches; + if (!~('' + attr).indexOf('.') && !isNaN(index)) { + if (bubble.isBubbling(this, 'change')) { + canEvent.dispatch.call(this, { + type: 'change', + target: this + }, [ + attr, + how, + newVal, + oldVal + ]); + } + if (how === 'add') { + patches = [{ + insert: newVal, + index: index, + deleteCount: 0, + type: 'splice' + }]; + canEvent.dispatch.call(this, { + type: how, + patches: patches + }, [ + newVal, + index + ]); + canEvent.dispatch.call(this, 'length', [this.length]); + } else if (how === 'remove') { + patches = [{ + index: index, + deleteCount: oldVal.length, + type: 'splice' + }]; + canEvent.dispatch.call(this, { + type: how, + patches: patches + }, [ + oldVal, + index + ]); + canEvent.dispatch.call(this, 'length', [this.length]); + } else { + canEvent.dispatch.call(this, how, [ + newVal, + index + ]); + } + } else { + Map.prototype._triggerChange.apply(this, arguments); + } + queues.batch.stop(); + }, + ___get: function (attr) { + if (attr) { + var computedAttr = this._computedAttrs[attr]; + if (computedAttr && computedAttr.compute) { + return canReflect.getValue(computedAttr.compute); + } + if (this[attr] && this[attr].isComputed && typeof this.constructor.prototype[attr] === 'function') { + return canReflect.getValue(this[attr]); + } else { + return this[attr]; + } + } else { + return this; + } + }, + __set: function (prop, value, current) { + prop = isNaN(+prop) || prop % 1 ? prop : +prop; + if (typeof prop === 'number') { + if (prop > this.length - 1) { + var newArr = new Array(prop + 1 - this.length); + newArr[newArr.length - 1] = value; + this.push.apply(this, newArr); + return newArr; + } else { + this.splice(prop, 1, value); + return this; + } + } + return Map.prototype.__set.call(this, '' + prop, value, current); + }, + ___set: function (attr, val) { + this[attr] = val; + if (+attr >= this.length) { + this.length = +attr + 1; + } + }, + __remove: function (prop, current) { + if (isNaN(+prop)) { + delete this[prop]; + this._triggerChange(prop, 'remove', undefined, current); + } else { + this.splice(prop, 1); + } + }, + _each: function (callback) { + var data = this.___get(); + for (var i = 0; i < data.length; i++) { + callback(data[i], i); + } + }, + serialize: function () { + return canReflect.serialize(this, CIDMap); + }, + splice: function (index, howMany) { + var args = canReflect.toArray(arguments), added = [], i, len, listIndex, allSame = args.length > 2; + index = index || 0; + for (i = 0, len = args.length - 2; i < len; i++) { + listIndex = i + 2; + args[listIndex] = this.__type(args[listIndex], listIndex); + added.push(args[listIndex]); + if (this[i + index] !== args[listIndex]) { + allSame = false; + } + } + if (allSame && this.length <= added.length) { + return added; + } + if (howMany === undefined) { + howMany = args[1] = this.length - index; + } + var removed = splice.apply(this, args); + if (!spliceRemovesProps) { + for (i = this.length; i < removed.length + this.length; i++) { + delete this[i]; + } + } + queues.batch.start(); + if (howMany > 0) { + bubble.removeMany(this, removed); + this._triggerChange('' + index, 'remove', undefined, removed); + } + if (args.length > 2) { + bubble.addMany(this, added); + this._triggerChange('' + index, 'add', added, removed); + } + queues.batch.stop(); + return removed; + } + }), getArgs = function (args) { + return args[0] && Array.isArray(args[0]) ? args[0] : canReflect.toArray(args); + }; + canReflect.eachKey({ + push: 'length', + unshift: 0 + }, function (where, name) { + var orig = [][name]; + List.prototype[name] = function () { + var args = [], len = where ? this.length : 0, i = arguments.length, res, val; + while (i--) { + val = arguments[i]; + args[i] = bubble.set(this, i, this.__type(val, i)); + } + res = orig.apply(this, args); + if (!this.comparator || args.length) { + this._triggerChange('' + len, 'add', args, undefined); + } + return res; + }; + }); + canReflect.eachKey({ + pop: 'length', + shift: 0 + }, function (where, name) { + List.prototype[name] = function () { + if (!this.length) { + return undefined; + } + var args = getArgs(arguments), len = where && this.length ? this.length - 1 : 0; + var res = [][name].apply(this, args); + this._triggerChange('' + len, 'remove', undefined, [res]); + if (res && res.removeEventListener) { + bubble.remove(this, res); + } + return res; + }; + }); + assign(List.prototype, { + indexOf: function (item, fromIndex) { + ObservationRecorder.add(this, 'length'); + for (var i = fromIndex || 0, len = this.length; i < len; i++) { + if (this.attr(i) === item) { + return i; + } + } + return -1; + }, + join: function () { + ObservationRecorder.add(this, 'length'); + return [].join.apply(this, arguments); + }, + reverse: function () { + var list = [].reverse.call(canReflect.toArray(this)); + return this.replace(list); + }, + slice: function () { + ObservationRecorder.add(this, 'length'); + var temp = Array.prototype.slice.apply(this, arguments); + return new this.constructor(temp); + }, + concat: function () { + var args = [], MapType = this.constructor.Map; + canReflect.each(arguments, function (arg) { + if (canReflect.isObservableLike(arg) && canReflect.isListLike(arg) || Array.isArray(arg)) { + var arr = canReflect.isObservableLike(arg) && canReflect.isListLike(arg) ? canReflect.toArray(arg) : arg; + canReflect.each(arr, function (innerArg) { + serializeNonTypes(MapType, innerArg, args); + }); + } else { + serializeNonTypes(MapType, arg, args); + } + }); + return new this.constructor(Array.prototype.concat.apply(canReflect.toArray(this), args)); + }, + forEach: function (cb, thisarg) { + var item; + for (var i = 0, len = this.attr('length'); i < len; i++) { + item = this.attr(i); + if (item !== undefined && cb.call(thisarg || item, item, i, this) === false) { + break; + } + } + return this; + }, + replace: function (newList) { + if (canReflect.isPromise(newList)) { + if (this._promise) { + this._promise.__isCurrentPromise = false; + } + var promise = this._promise = newList; + promise.__isCurrentPromise = true; + var self = this; + newList.then(function (newList) { + if (promise.__isCurrentPromise) { + self.replace(newList); + } + }); + } else { + newList = newList === undefined ? [] : canReflect.toArray(newList); + this.splice.apply(this, [ + 0, + this.length + ].concat(newList)); + } + return this; + }, + filter: function (callback, thisArg) { + var filteredList = new this.constructor(), self = this, filtered; + this.forEach(function (item, index, list) { + filtered = callback.call(thisArg || self, item, index, self); + if (filtered) { + filteredList.push(item); + } + }); + return filteredList; + }, + map: function (callback, thisArg) { + var filteredList = new List(), self = this; + this.forEach(function (item, index, list) { + var mapped = callback.call(thisArg || self, item, index, self); + filteredList.push(mapped); + }); + return filteredList; + }, + sort: function (compareFunction) { + var sorting = Array.prototype.slice.call(this); + Array.prototype.sort.call(sorting, compareFunction); + this.splice.apply(this, [ + 0, + sorting.length + ].concat(sorting)); + return this; + } + }); + var oldType = Map.prototype.__type; + Map.prototype.__type = function (value, prop) { + if (typeof value === 'object' && Array.isArray(value)) { + var cached = mapHelpers.getMapFromObject(value); + if (cached) { + return cached; + } + return new List(value); + } + return oldType.apply(this, arguments); + }; + var oldSetup = Map.setup; + Map.setup = function () { + oldSetup.apply(this, arguments); + if (!(this.prototype instanceof List)) { + this.List = Map.List.extend({ Map: this }, {}); + } + }; + if (!types.DefaultList) { + types.DefaultList = List; + } + canReflect.assignSymbols(List.prototype, { + 'can.isMoreListLikeThanMapLike': true, + 'can.isListLike': true, + 'can.getKeyValue': List.prototype._get, + 'can.setKeyValue': List.prototype._set, + 'can.deleteKeyValue': List.prototype._remove, + 'can.getOwnEnumerableKeys': function () { + return Object.keys(this._data || {}).concat(this.map(function (val, index) { + return index; + })); + }, + 'can.assignDeep': function (source) { + queues.batch.start(); + canReflect.assignDeepList(this, source); + queues.batch.stop(); + }, + 'can.updateDeep': function (source) { + queues.batch.start(); + canReflect.updateDeepList(this, source); + queues.batch.stop(); + }, + 'can.unwrap': mapHelpers.reflectUnwrap, + 'can.serialize': mapHelpers.reflectSerialize, + 'can.onKeysAdded': function (handler) { + this[canSymbol.for('can.onKeyValue')]('add', handler); + }, + 'can.onKeysRemoved': function (handler) { + this[canSymbol.for('can.onKeyValue')]('remove', handler); + }, + 'can.splice': function (index, deleteCount, insert) { + this.splice.apply(this, [ + index, + deleteCount + ].concat(insert)); + } + }); + Map.List = List; + module.exports = namespace.List = List; +}); +/*can-list@4.2.0#can-list_test*/ +define('can-list@4.2.0#can-list_test', [ + 'require', + 'exports', + 'module', + 'can-list', + 'steal-qunit', + 'can-observation', + 'can-map', + 'can-reflect', + 'can-symbol' +], function (require, exports, module) { + var List = require('can-list'); + var QUnit = require('steal-qunit'); + var Observation = require('can-observation'); + var Map = require('can-map'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + QUnit.module('can-list'); + test('list attr changes length', function () { + var l = new List([ + 0, + 1, + 2 + ]); + l.attr(3, 3); + equal(l.length, 4); + }); + test('removeAttr on list', function () { + var l = new List([ + 0, + 1, + 2 + ]); + l.removeAttr(1); + equal(l.attr('length'), 2); + deepEqual(l.attr(), [ + 0, + 2 + ]); + }); + test('list splice', function () { + var l = new List([ + 0, + 1, + 2, + 3 + ]), first = true; + l.bind('change', function (ev, attr, how, newVals, oldVals) { + equal(attr, '1'); + if (first) { + equal(how, 'remove', 'removing items'); + equal(newVals, undefined, 'no new Vals'); + } else { + deepEqual(newVals, [ + 'a', + 'b' + ], 'got the right newVals'); + equal(how, 'add', 'adding items'); + } + first = false; + }); + l.splice(1, 2, 'a', 'b'); + deepEqual(l.serialize(), [ + 0, + 'a', + 'b', + 3 + ], 'serialized'); + }); + test('list pop', function () { + var l = new List([ + 0, + 1, + 2, + 3 + ]); + l.bind('change', function (ev, attr, how, newVals, oldVals) { + equal(attr, '3'); + equal(how, 'remove'); + equal(newVals, undefined); + deepEqual(oldVals, [3]); + }); + l.pop(); + deepEqual(l.serialize(), [ + 0, + 1, + 2 + ]); + }); + test('remove nested property in item of array map', function () { + var state = new List([{ nested: true }]); + state.bind('change', function (ev, attr, how, newVal, old) { + equal(attr, '0.nested'); + equal(how, 'remove'); + deepEqual(old, true); + }); + state.removeAttr('0.nested'); + equal(undefined, state.attr('0.nested')); + }); + test('pop unbinds', function () { + var l = new List([{ foo: 'bar' }]); + var o = l.attr(0), count = 0; + l.bind('change', function (ev, attr, how, newVal, oldVal) { + count++; + if (count === 1) { + equal(attr, '0.foo', 'count is set'); + } else if (count === 2) { + equal(how, 'remove'); + equal(attr, '0'); + } else { + ok(false, 'called too many times'); + } + }); + equal(o.attr('foo'), 'bar', 'read foo property'); + o.attr('foo', 'car'); + l.pop(); + o.attr('foo', 'bad'); + }); + test('splice unbinds', function () { + var l = new List([{ foo: 'bar' }]); + var o = l.attr(0), count = 0; + l.bind('change', function (ev, attr, how, newVal, oldVal) { + count++; + if (count === 1) { + equal(attr, '0.foo', 'count is set'); + } else if (count === 2) { + equal(how, 'remove'); + equal(attr, '0'); + } else { + ok(false, 'called too many times'); + } + }); + equal(o.attr('foo'), 'bar'); + o.attr('foo', 'car'); + l.splice(0, 1); + o.attr('foo', 'bad'); + }); + test('always gets right attr even after moving array items', function () { + var l = new List([{ foo: 'bar' }]); + var o = l.attr(0); + l.unshift('A new Value'); + l.bind('change', function (ev, attr, how) { + equal(attr, '1.foo'); + }); + o.attr('foo', 'led you'); + }); + test('Array accessor methods', 11, function () { + var l = new List([ + 'a', + 'b', + 'c' + ]), sliced = l.slice(2), joined = l.join(' | '), concatenated = l.concat([ + 2, + 1 + ], new List([0])); + ok(sliced instanceof List, 'Slice is an Observable list'); + equal(sliced.length, 1, 'Sliced off two elements'); + equal(sliced[0], 'c', 'Single element as expected'); + equal(joined, 'a | b | c', 'Joined list properly'); + ok(concatenated instanceof List, 'Concatenated is an Observable list'); + deepEqual(concatenated.serialize(), [ + 'a', + 'b', + 'c', + 2, + 1, + 0 + ], 'List concatenated properly'); + l.forEach(function (letter, index) { + ok(true, 'Iteration'); + if (index === 0) { + equal(letter, 'a', 'First letter right'); + } + if (index === 2) { + equal(letter, 'c', 'Last letter right'); + } + }); + }); + test('Concatenated list items Equal original', function () { + var l = new List([ + { firstProp: 'Some data' }, + { secondProp: 'Next data' } + ]), concatenated = l.concat([ + { hello: 'World' }, + { foo: 'Bar' } + ]); + ok(l[0] === concatenated[0], 'They are Equal'); + ok(l[1] === concatenated[1], 'They are Equal'); + }); + test('Lists with maps concatenate properly', function () { + var Person = Map.extend(); + var People = List.extend({ Map: Person }, {}); + var Genius = Person.extend(); + var Animal = Map.extend(); + var me = new Person({ name: 'John' }); + var animal = new Animal({ name: 'Tak' }); + var genius = new Genius({ name: 'Einstein' }); + var hero = { name: 'Ghandi' }; + var people = new People([]); + var specialPeople = new People([ + genius, + hero + ]); + people = people.concat([ + me, + animal, + specialPeople + ], specialPeople, [ + 1, + 2 + ], 3); + ok(people.attr('length') === 8, 'List length is right'); + ok(people[0] === me, 'Map in list === vars created before concat'); + ok(people[1] instanceof Person, 'Animal got serialized to Person'); + }); + test('splice removes items in IE (#562)', function () { + var l = new List(['a']); + l.splice(0, 1); + ok(!l.attr(0), 'all props are removed'); + }); + test('reverse triggers add/remove events (#851)', function () { + expect(6); + var l = new List([ + 1, + 2, + 3 + ]); + l.bind('change', function () { + ok(true, 'change should be called'); + }); + l.bind('set', function () { + ok(false, 'set should not be called'); + }); + l.bind('add', function () { + ok(true, 'add called'); + }); + l.bind('remove', function () { + ok(true, 'remove called'); + }); + l.bind('length', function () { + ok(true, 'length should be called'); + }); + l.reverse(); + }); + test('filter', function () { + var l = new List([ + { + id: 1, + name: 'John' + }, + { + id: 2, + name: 'Mary' + } + ]); + var filtered = l.filter(function (item) { + return item.name === 'Mary'; + }); + notEqual(filtered._cid, l._cid, 'not same object'); + equal(filtered.length, 1, 'one item'); + equal(filtered[0].name, 'Mary', 'filter works'); + }); + test('removing expandos on lists', function () { + var list = new List([ + 'a', + 'b' + ]); + list.removeAttr('foo'); + equal(list.length, 2); + }); + test('No Add Events if List Splice adds the same items that it is removing. (#1277, #1399)', function () { + var list = new List([ + 'a', + 'b' + ]); + list.bind('add', function () { + ok(false, 'Add callback should not be called.'); + }); + list.bind('remove', function () { + ok(false, 'Remove callback should not be called.'); + }); + var result = list.splice(0, 2, 'a', 'b'); + deepEqual(result, [ + 'a', + 'b' + ]); + }); + test('add event always returns an array as the value (#998)', function () { + var list = new List([]), msg; + list.bind('add', function (ev, newElements, index) { + deepEqual(newElements, [4], msg); + }); + msg = 'works on push'; + list.push(4); + list.pop(); + msg = 'works on attr()'; + list.attr(0, 4); + list.pop(); + msg = 'works on replace()'; + list.replace([4]); + }); + test('Setting with .attr() out of bounds of length triggers add event with leading undefineds', function () { + var list = new List([1]); + list.bind('add', function (ev, newElements, index) { + deepEqual(newElements, [ + undefined, + undefined, + 4 + ], 'Leading undefineds are included'); + equal(index, 1, 'Index takes into account the leading undefineds from a .attr()'); + }); + list.attr(3, 4); + }); + test('No events should fire if removals happened on empty arrays', function () { + var list = new List([]), msg; + list.bind('remove', function (ev, removed, index) { + ok(false, msg); + }); + msg = 'works on pop'; + list.pop(); + msg = 'works on shift'; + list.shift(); + ok(true, 'No events were fired.'); + }); + test('setting an index out of bounds does not create an array', function () { + expect(1); + var l = new List(); + l.attr('1', 'foo'); + equal(l.attr('1'), 'foo'); + }); + test('splice with similar but less items works (#1606)', function () { + var list = new List([ + 'aa', + 'bb', + 'cc' + ]); + list.splice(0, list.length, 'aa', 'cc', 'dd'); + deepEqual(list.attr(), [ + 'aa', + 'cc', + 'dd' + ]); + list.splice(0, list.length, 'aa', 'cc'); + deepEqual(list.attr(), [ + 'aa', + 'cc' + ]); + }); + test('filter returns same list type (#1744)', function () { + var ParentList = List.extend(); + var ChildList = ParentList.extend(); + var children = new ChildList([ + 1, + 2, + 3 + ]); + ok(children.filter(function () { + }) instanceof ChildList); + }); + test('reverse returns the same list instance (#1744)', function () { + var ParentList = List.extend(); + var ChildList = ParentList.extend(); + var children = new ChildList([ + 1, + 2, + 3 + ]); + ok(children.reverse() === children); + }); + test('slice and join are observable by a compute (#1884)', function () { + expect(2); + var list = new List([ + 1, + 2, + 3 + ]); + var sliced = new Observation(function () { + return list.slice(0, 1); + }); + canReflect.onValue(sliced, function (newVal) { + deepEqual(newVal.attr(), [2], 'got a new List'); + }); + var joined = new Observation(function () { + return list.join(','); + }); + canReflect.onValue(joined, function (newVal) { + equal(newVal, '2,3', 'joined is observable'); + }); + list.shift(); + }); + test('list is always updated with the last promise passed to replace (#2136)', function () { + var list = new List(); + stop(); + list.replace(new Promise(function (resolve) { + setTimeout(function () { + resolve(['A']); + setTimeout(function () { + equal(list.attr(0), 'B', 'list set to last promise\'s value'); + start(); + }, 10); + }, 20); + })); + list.replace(new Promise(function (resolve) { + setTimeout(function () { + resolve(['B']); + }, 10); + })); + }); + test('forEach callback', function () { + var list = new List([]), counter = 0; + list.attr(9, 'foo'); + list.forEach(function (element, index, list) { + counter++; + }); + equal(counter, 1, 'Should not be invoked for uninitialized attr keys'); + }); + test('filter with context', function () { + var l = new List([{ id: 1 }]); + var context = {}; + var contextWasCorrect = false; + l.filter(function () { + contextWasCorrect = this === context; + return true; + }, context); + equal(contextWasCorrect, true, 'context was correctly passed'); + }); + test('map with context', function () { + var l = new List([{ id: 1 }]); + var context = {}; + var contextWasCorrect = false; + l.map(function () { + contextWasCorrect = this === context; + return true; + }, context); + equal(contextWasCorrect, true, 'context was correctly passed'); + }); + test('works with can-reflect', 11, function () { + var a = new Map({ foo: 4 }); + var b = new List([ + 'foo', + 'bar' + ]); + QUnit.equal(canReflect.getKeyValue(b, '0'), 'foo', 'unbound value'); + var handler = function (newValue) { + QUnit.equal(newValue, 'quux', 'observed new value'); + }; + QUnit.ok(!canReflect.isValueLike(b), 'isValueLike is false'); + QUnit.ok(canReflect.isMapLike(b), 'isMapLike is true'); + QUnit.ok(canReflect.isListLike(b), 'isListLike is false'); + QUnit.ok(!canReflect.keyHasDependencies(b, 'length'), 'keyHasDependencies -- false'); + b._computedAttrs['length'] = { + compute: new Observation(function () { + return a.attr('foo'); + }, null) + }; + b._computedAttrs['length'].compute.start(); + QUnit.ok(canReflect.keyHasDependencies(b, 'length'), 'keyHasDependencies -- true'); + canReflect.onKeysAdded(b, handler); + canReflect.onKeysRemoved(b, handler); + var handlers = b[canSymbol.for('can.meta')].handlers; + QUnit.ok(handlers.get(['add']).length, 'add handler added'); + QUnit.ok(handlers.get(['remove']).length, 'remove handler added'); + b.push('quux'); + QUnit.equal(canReflect.getKeyValue(b, 'length'), '4', 'bound value'); + b.pop(); + }); + QUnit.test('can-reflect setKeyValue', function () { + var a = new Map({ 'a': 'b' }); + canReflect.setKeyValue(a, 'a', 'c'); + QUnit.equal(a.attr('a'), 'c', 'setKeyValue'); + }); + QUnit.test('can-reflect getKeyDependencies', function () { + var a = new Map({ foo: 4 }); + var b = new List([ + 'foo', + 'bar' + ]); + ok(!canReflect.getKeyDependencies(b, 'length'), 'No dependencies before binding'); + b._computedAttrs.length = { + compute: new Observation(function () { + return a.attr('foo'); + }, null) + }; + b._computedAttrs.length.compute.start(); + ok(canReflect.getKeyDependencies(b, 'length'), 'dependencies exist'); + ok(canReflect.getKeyDependencies(b, 'length').valueDependencies.has(b._computedAttrs.length.compute), 'dependencies returned'); + }); + QUnit.test('registered symbols', function () { + var a = new Map({ 'a': 'a' }); + ok(a[canSymbol.for('can.isMapLike')], 'can.isMapLike'); + equal(a[canSymbol.for('can.getKeyValue')]('a'), 'a', 'can.getKeyValue'); + a[canSymbol.for('can.setKeyValue')]('a', 'b'); + equal(a.attr('a'), 'b', 'can.setKeyValue'); + function handler(val) { + equal(val, 'c', 'can.onKeyValue'); + } + a[canSymbol.for('can.onKeyValue')]('a', handler); + a.attr('a', 'c'); + a[canSymbol.for('can.offKeyValue')]('a', handler); + a.attr('a', 'd'); + }); + QUnit.test('onPatches', function () { + var list = new List([ + 'a', + 'b' + ]); + var PATCHES = [ + [{ + deleteCount: 2, + index: 0, + type: 'splice' + }], + [{ + index: 0, + insert: [ + 'A', + 'B' + ], + deleteCount: 0, + type: 'splice' + }] + ]; + var handlerCalls = 0; + var handler = function (patches) { + QUnit.deepEqual(patches, PATCHES[handlerCalls], 'patches looked right for ' + handlerCalls); + handlerCalls++; + }; + list[canSymbol.for('can.onPatches')](handler, 'notify'); + list.replace([ + 'A', + 'B' + ]); + list[canSymbol.for('can.offPatches')](handler, 'notify'); + list.replace([ + '1', + '2' + ]); + }); + QUnit.test('can.onInstancePatches basics', function () { + var People = List.extend({}); + var calls = []; + function handler(obj, patches) { + calls.push([ + obj, + patches + ]); + } + People[canSymbol.for('can.onInstancePatches')](handler); + var list = new People([ + 1, + 2 + ]); + list.push(3); + list.attr('count', 8); + People[canSymbol.for('can.offInstancePatches')](handler); + list.push(4); + list.attr('count', 7); + QUnit.deepEqual(calls, [ + [ + list, + [{ + type: 'splice', + index: 2, + deleteCount: 0, + insert: [3] + }] + ], + [ + list, + [{ + type: 'set', + key: 'count', + value: 8 + }] + ] + ]); + }); + QUnit.test('can.onInstanceBoundChange basics', function () { + var People = List.extend({}); + var calls = []; + function handler(obj, patches) { + calls.push([ + obj, + patches + ]); + } + People[canSymbol.for('can.onInstanceBoundChange')](handler); + var people = new People([]); + var bindHandler = function () { + }; + canReflect.onKeyValue(people, 'length', bindHandler); + canReflect.offKeyValue(people, 'length', bindHandler); + People[canSymbol.for('can.offInstanceBoundChange')](handler); + canReflect.onKeyValue(people, 'length', bindHandler); + canReflect.offKeyValue(people, 'length', bindHandler); + QUnit.deepEqual(calls, [ + [ + people, + true + ], + [ + people, + false + ] + ]); + }); + QUnit.test('list.sort a simple list', function () { + var myList = new List([ + 'Marshall', + 'Austin', + 'Hyrum' + ]); + myList.sort(); + equal(myList.length, 3); + equal(myList[0], 'Austin'); + equal(myList[1], 'Hyrum'); + equal(myList[2], 'Marshall', 'Basic list was properly sorted.'); + }); + QUnit.test('list.sort a list of objects', function () { + var objList = new List([ + { + id: 1, + name: 'Marshall' + }, + { + id: 2, + name: 'Austin' + }, + { + id: 3, + name: 'Hyrum' + } + ]); + objList.sort(function (a, b) { + if (a.name < b.name) { + return -1; + } else if (a.name > b.name) { + return 1; + } else { + return 0; + } + }); + equal(objList.length, 3); + equal(objList[0].name, 'Austin'); + equal(objList[1].name, 'Hyrum'); + equal(objList[2].name, 'Marshall', 'List of objects was properly sorted.'); + }); + QUnit.test('list.sort a list of objects without losing reference (#137)', function () { + var unSorted = new List([ + { id: 3 }, + { id: 2 }, + { id: 1 } + ]); + var sorted = unSorted.slice(0).sort(function (a, b) { + return a.id > b.id ? 1 : a.id < b.id ? -1 : 0; + }); + equal(unSorted[0], sorted[2], 'items should be equal'); + }); +}); +/*can-map@4.3.3#can-map_test*/ +define('can-map@4.3.3#can-map_test', [ + 'require', + 'exports', + 'module', + 'can-map', + 'steal-qunit', + 'can-compute', + 'can-observation-recorder', + 'can-construct', + 'can-stache-key', + 'can-reflect', + 'can-symbol', + 'can-queues', + 'can-reflect-tests/observables/map-like/type/type' +], function (require, exports, module) { + var Map = require('can-map'); + var QUnit = require('steal-qunit'); + var canCompute = require('can-compute'); + var ObservationRecorder = require('can-observation-recorder'); + var Construct = require('can-construct'); + var observeReader = require('can-stache-key'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var queues = require('can-queues'); + QUnit.module('can-map'); + test('Basic Map', 4, function () { + var state = new Map({ + category: 5, + productType: 4 + }); + state.bind('change', function (ev, attr, how, val, old) { + equal(attr, 'category', 'correct change name'); + equal(how, 'set'); + equal(val, 6, 'correct'); + equal(old, 5, 'correct'); + }); + state.attr('category', 6); + state.unbind('change'); + }); + test('Nested Map', 5, function () { + var me = new Map({ + name: { + first: 'Justin', + last: 'Meyer' + } + }); + ok(me.attr('name') instanceof Map); + me.bind('change', function (ev, attr, how, val, old) { + equal(attr, 'name.first', 'correct change name'); + equal(how, 'set'); + equal(val, 'Brian', 'correct'); + equal(old, 'Justin', 'correct'); + }); + me.attr('name.first', 'Brian'); + me.unbind('change'); + }); + test('remove attr', function () { + var state = new Map({ + category: 5, + productType: 4 + }); + state.removeAttr('category'); + deepEqual(Map.keys(state), ['productType'], 'one property'); + }); + test('remove attr on key with dot', function () { + var state = new Map({ + 'key.with.dots': 12, + productType: 4 + }); + var state2 = new Map({ + 'key.with.dots': 4, + key: { 'with': { someValue: 20 } } + }); + state.removeAttr('key.with.dots'); + state2.removeAttr('key.with.someValue'); + deepEqual(Map.keys(state), ['productType'], 'one property'); + deepEqual(Map.keys(state2), [ + 'key.with.dots', + 'key' + ], 'two properties'); + deepEqual(Map.keys(state2.key['with']), [], 'zero properties'); + }); + test('nested event handlers are not run by changing the parent property (#280)', function () { + var person = new Map({ name: { first: 'Justin' } }); + person.bind('name.first', function (ev, newName) { + ok(false, 'name.first should never be called'); + }); + person.bind('name', function () { + ok(true, 'name event triggered'); + }); + person.attr('name', { first: 'Hank' }); + }); + test('cyclical objects (#521)', function () { + var foo = {}; + foo.foo = foo; + var fooed = new Map(foo); + ok(true, 'did not cause infinate recursion'); + ok(fooed.attr('foo') === fooed, 'map points to itself'); + var me = { name: 'Justin' }; + var references = { + husband: me, + friend: me + }; + var ref = new Map(references); + ok(ref.attr('husband') === ref.attr('friend'), 'multiple properties point to the same thing'); + }); + test('_cid add to original object', function () { + var map = new Map(), obj = { 'name': 'thecountofzero' }; + map.attr('myObj', obj); + ok(!obj._cid, '_cid not added to original object'); + }); + test('Map serialize triggers reading (#626)', function () { + var old = ObservationRecorder.add; + var attributesRead = []; + var readingTriggeredForKeys = false; + ObservationRecorder.add = function (object, attribute) { + if (attribute === '__keys') { + readingTriggeredForKeys = true; + } else { + attributesRead.push(attribute); + } + }; + var testMap = new Map({ + cats: 'meow', + dogs: 'bark' + }); + testMap.serialize(); + ok(attributesRead.indexOf('cats') !== -1 && attributesRead.indexOf('dogs') !== -1, 'map serialization triggered __reading on all attributes'); + ok(readingTriggeredForKeys, 'map serialization triggered __reading for __keys'); + ObservationRecorder.add = old; + }); + test('Test top level attributes', 7, function () { + var test = new Map({ + 'my.enable': false, + 'my.item': true, + 'my.count': 0, + 'my.newCount': 1, + 'my': { + 'value': true, + 'nested': { 'value': 100 } + } + }); + equal(test.attr('my.value'), true, 'correct'); + equal(test.attr('my.nested.value'), 100, 'correct'); + ok(test.attr('my.nested') instanceof Map); + equal(test.attr('my.enable'), false, 'falsey (false) value accessed correctly'); + equal(test.attr('my.item'), true, 'truthey (true) value accessed correctly'); + equal(test.attr('my.count'), 0, 'falsey (0) value accessed correctly'); + equal(test.attr('my.newCount'), 1, 'falsey (1) value accessed correctly'); + }); + test('serializing cycles', function () { + var map1 = new Map({ name: 'map1' }); + var map2 = new Map({ name: 'map2' }); + map1.attr('map2', map2); + map2.attr('map1', map1); + var res = map1.serialize(); + equal(res.name, 'map1'); + equal(res.map2.name, 'map2'); + }); + test('Unbinding from a map with no bindings doesn\'t throw an error (#1015)', function () { + expect(0); + var test = new Map({}); + try { + test.unbind('change'); + } catch (e) { + ok(false, 'No error should be thrown'); + } + }); + test('Fast dispatch event still has target and type (#1082)', 4, function () { + var data = new Map({ name: 'CanJS' }); + data.bind('change', function (ev) { + equal(ev.type, 'change'); + equal(ev.target, data); + }); + data.bind('name', function (ev) { + equal(ev.type, 'name'); + equal(ev.target, data); + }); + data.attr('name', 'David'); + }); + test('map passed to Map constructor (#1166)', function () { + function y() { + } + var map = new Map({ + x: 1, + y: y + }); + var res = new Map(map); + deepEqual(res.attr(), { + x: 1, + y: y + }, 'has the same properties'); + }); + test('constructor passed to scope is threated as a property (#1261)', function () { + var Constructor = Construct.extend({}); + var MyMap = Map.extend({ Todo: Constructor }); + var m = new MyMap(); + equal(m.attr('Todo'), Constructor); + }); + test('_bindings count maintained after calling .off() on undefined property (#1490) ', function () { + var map = new Map({ test: 1 }); + map.on('test', function () { + }); + var handlers = map[canSymbol.for('can.meta')].handlers; + equal(handlers.get([]).length, 1, 'The number of bindings is correct'); + map.off('undefined_property'); + equal(handlers.get([]).length, 1, 'The number of bindings is still correct'); + }); + test('Should be able to get and set attribute named \'watch\' on Map in Firefox', function () { + var map = new Map({}); + map.attr('watch'); + ok(true, 'can have attribute named \'watch\' on a Map instance'); + }); + test('Should be able to get and set attribute named \'unwatch\' on Map in Firefox', function () { + var map = new Map({}); + map.attr('unwatch'); + ok(true, 'can have attribute named \'unwatch\' on a Map instance'); + }); + test('should get an empty string property value correctly', function () { + var map = new Map({ + foo: 'foo', + '': 'empty string' + }); + equal(map.attr(''), 'empty string'); + }); + test('ObserveReader - can.Construct derived classes should be considered objects, not functions (#450)', function () { + var foostructor = Map.extend({ text: 'bar' }, {}), obj = { + next_level: { + thing: foostructor, + text: 'In the inner context' + } + }, read; + foostructor.self = foostructor; + read = observeReader.read(obj, observeReader.reads('next_level.thing.self.text')); + equal(read.value, 'bar', 'static properties on a can.Construct-based function'); + read = observeReader.read(obj, observeReader.reads('next_level.thing.self'), { isArgument: true }); + ok(read.value === foostructor, 'arguments shouldn\'t be executed'); + }); + test('works with can-reflect', 7, function () { + var b = new Map({ 'foo': 'bar' }); + var c = new (Map.extend({ + 'baz': canCompute(function () { + return b.attr('foo'); + }) + }))({ + 'foo': 'bar', + thud: 'baz' + }); + QUnit.equal(canReflect.getKeyValue(b, 'foo'), 'bar', 'unbound value'); + function bazHandler(newValue) { + QUnit.equal(newValue, 'quux', 'observed new value on baz'); + canReflect.offKeyValue(c, 'baz', bazHandler); + } + function thudHandler(newValue) { + QUnit.equal(newValue, 'quux', 'observed new value on thud'); + canReflect.offKeyValue(c, 'thud', thudHandler); + } + QUnit.ok(!canReflect.isValueLike(c), 'isValueLike is false'); + QUnit.ok(canReflect.isMapLike(c), 'isMapLike is true'); + QUnit.ok(!canReflect.isListLike(c), 'isListLike is false'); + canReflect.onKeyValue(c, 'baz', bazHandler); + canReflect.onKeyValue(c, 'thud', thudHandler); + b.attr('foo', 'quux'); + c.attr('thud', 'quux'); + QUnit.equal(canReflect.getKeyValue(c, 'baz'), 'quux', 'bound value'); + b.attr('foo', 'thud'); + c.attr('baz', 'jeek'); + }); + QUnit.test('onKeyValue and queues', function () { + var b = new Map({ 'foo': 'bar' }); + var order = []; + canReflect.onKeyValue(b, 'foo', function () { + order.push('onKeyValue'); + }, 'notify'); + queues.batch.start(); + queues.mutateQueue.enqueue(function () { + order.push('mutate'); + }); + b.attr('foo', 'baz'); + queues.batch.stop(); + QUnit.deepEqual(order, [ + 'onKeyValue', + 'mutate' + ]); + }); + QUnit.test('can-reflect setKeyValue', function () { + var a = new Map({ 'a': 'b' }); + canReflect.setKeyValue(a, 'a', 'c'); + QUnit.equal(a.attr('a'), 'c', 'setKeyValue'); + }); + QUnit.test('can-reflect getKeyDependencies', function () { + var a = new Map({ 'a': 'a' }); + var b = new (Map.extend({ + 'a': canCompute(function () { + return a.attr('a'); + }), + 'b': 'b' + }))(); + ok(canReflect.getKeyDependencies(b, 'a'), 'Dependencies on computed attr'); + ok(!canReflect.getKeyDependencies(b, 'b'), 'No dependencies on data attr'); + b.on('a', function () { + }); + ok(canReflect.getKeyDependencies(b, 'a').valueDependencies.has(b._computedAttrs.a.compute), 'dependencies returned'); + ok(canReflect.getValueDependencies(b._computedAttrs.a.compute).valueDependencies, 'dependencies returned from compute'); + }); + QUnit.test('registered symbols', function () { + var a = new Map({ 'a': 'a' }); + ok(a[canSymbol.for('can.isMapLike')], 'can.isMapLike'); + equal(a[canSymbol.for('can.getKeyValue')]('a'), 'a', 'can.getKeyValue'); + a[canSymbol.for('can.setKeyValue')]('a', 'b'); + equal(a.attr('a'), 'b', 'can.setKeyValue'); + function handler(val) { + equal(this, a); + equal(val, 'c', 'can.onKeyValue'); + } + a[canSymbol.for('can.onKeyValue')]('a', handler); + a.attr('a', 'c'); + a[canSymbol.for('can.offKeyValue')]('a', handler); + a.attr('a', 'd'); + }); + require('can-reflect-tests/observables/map-like/type/type')('Map', function () { + return Map.extend({}); + }); + QUnit.test('can.isBound', function () { + var Person = Map.extend({ + first: 'any', + last: 'any' + }); + var p = new Person(); + QUnit.ok(!p[canSymbol.for('can.isBound')](), 'not bound'); + }); + QUnit.test('prototype properties', function (assert) { + var MyMap = Map.extend({ letters: 'ABC' }); + var map = new MyMap(); + assert.equal(map.attr('letters'), 'ABC'); + }); + QUnit.test('can read numbers', function (assert) { + var map = new Map({ 0: 'zero' }); + assert.equal(canReflect.getKeyValue(map, 0), 'zero'); + assert.equal(map.attr(0), 'zero'); + canReflect.onKeyValue(0, function handler(ev, newVal) { + assert.equal(newVal, 'one'); + canReflect.offKeyValue(0, handler); + }); + canReflect.setKeyValue(map, 0, 'one'); + }); + QUnit.test('attr should work when remove === \'true\'', function (assert) { + var map = new Map({ 0: 'zero' }); + map.attr({ 1: 'one' }, 'true'); + assert.equal(canReflect.getKeyValue(map, 0), undefined); + assert.equal(map.attr(0), undefined); + assert.equal(canReflect.getKeyValue(map, 1), 'one'); + assert.equal(map.attr(1), 'one'); + }); + QUnit.test('constructor should not bind on __keys (#106)', function (assert) { + var map; + var comp = canCompute(function () { + map = new Map(); + }); + canReflect.onValue(comp, function () { + }); + map.attr('foo', 'bar'); + assert.equal(map.attr('foo'), 'bar', 'map should not be reset'); + }); + QUnit.test('.attr(props) should overwrite if _legacyAttrBehavior is true (#112)', function () { + Map.prototype._legacyAttrBehavior = true; + var myMap1Instance = new Map({ prop1: new Map() }); + var changes = 0; + myMap1Instance.on('prop1', function () { + changes++; + }); + var map2 = new Map({ prop1: 'xyz' }); + myMap1Instance.attr({ 'prop1': map2 }); + delete Map.prototype._legacyAttrBehavior; + QUnit.equal(changes, 1, 'caused a change event'); + QUnit.equal(myMap1Instance.attr('prop1'), map2, 'overwrite with maps'); + }); + QUnit.test('.attr() leaves typed instances alone if _legacyAttrBehavior is true (#111)', function () { + Map.prototype._legacyAttrBehavior = true; + function MyClass(value) { + this.value = value; + } + MyClass.prototype.log = function () { + return this.value; + }; + var myMap = new Map({ myClass: new MyClass(5) }); + QUnit.equal(myMap.attr().myClass, myMap.attr('myClass')); + delete Map.prototype._legacyAttrBehavior; + }); + QUnit.test('.serialize() leaves typed instances alone if _legacyAttrBehavior is true', function () { + function MyClass(value) { + this.value = value; + } + var myMap = new Map({ + _legacyAttrBehavior: true, + myClass: new MyClass('foo') + }); + var ser = myMap.serialize(); + QUnit.equal(ser.myClass, myMap.attr('myClass')); + }); + QUnit.test('keys with undefined values should not be dropped (#118)', function () { + var obj1 = { 'keepMe': undefined }; + var map = new Map(obj1); + map.attr('foo', undefined); + var keys = Map.keys(map); + QUnit.deepEqual(keys, [ + 'keepMe', + 'foo' + ]); + }); + QUnit.test('Can assign nested properties that are not CanMaps', function () { + var MyType = function () { + this.one = 'one'; + this.two = 'two'; + this.three = 'three'; + }; + MyType.prototype[canSymbol.for('can.onKeyValue')] = function () { + }; + MyType.prototype[canSymbol.for('can.isMapLike')] = true; + var map = new Map({ + _legacyAttrBehavior: true, + foo: 'bar', + prop: new MyType() + }); + map.attr({ + prop: { + one: '1', + two: '2' + } + }); + QUnit.equal(map.attr('prop.one'), '1'); + QUnit.equal(map.attr('prop.two'), '2'); + QUnit.equal(map.attr('prop.three'), 'three'); + map.attr({ + prop: { + one: 'one', + two: 'two' + } + }, true); + QUnit.equal(map.attr('prop.one'), 'one'); + QUnit.equal(map.attr('prop.two'), 'two'); + QUnit.equal(map.attr('prop.three'), undefined); + }); +}); +/*can-map-define@4.3.4#can-map-define*/ +define('can-map-define@4.3.4#can-map-define', [ + 'require', + 'exports', + 'module', + 'can-log/dev/dev', + 'can-assign', + 'can-event-queue/map/map', + 'can-queues', + 'can-map/map-helpers', + 'can-map', + 'can-compute', + 'can-reflect', + 'can-observation-recorder', + 'can-list' +], function (require, exports, module) { + 'use strict'; + var dev = require('can-log/dev/dev'); + var extend = require('can-assign'); + var mapEventsMixin = require('can-event-queue/map/map'); + var queues = require('can-queues'); + var mapHelpers = require('can-map/map-helpers'); + var CanMap = require('can-map'); + var compute = require('can-compute'); + var canReflect = require('can-reflect'); + var ObservationRecorder = require('can-observation-recorder'); + require('can-list'); + var define = {}; + var hasDefaultForSerialize = function (defaultDefinition) { + return typeof defaultDefinition === 'object' && 'serialize' in defaultDefinition; + }; + var getDefaultForSerialize = function (defaultDefinition) { + var shouldSerialize = true; + if (hasDefaultForSerialize(defaultDefinition)) { + shouldSerialize = !!defaultDefinition.serialize; + } + return shouldSerialize; + }; + var keysForDefinition = function (definitions) { + var keys = []; + var defaultDefinition = definitions && definitions['*']; + for (var prop in definitions) { + var definition = definitions[prop]; + var shouldSerialize = getDefaultForSerialize(defaultDefinition); + if (typeof definition === 'object' && 'serialize' in definition) { + shouldSerialize = !!definition.serialize; + } else if (typeof definition === 'object' && !hasDefaultForSerialize(defaultDefinition)) { + shouldSerialize = !definition.get; + } + if (shouldSerialize) { + keys.push(prop); + } + } + return keys; + }; + var getPropDefineBehavior = function (behavior, attr, define) { + var prop, defaultProp; + if (define) { + prop = define[attr]; + defaultProp = define['*']; + if (prop && prop[behavior] !== undefined) { + return prop[behavior]; + } else if (defaultProp && defaultProp[behavior] !== undefined) { + return defaultProp[behavior]; + } + } + }; + mapHelpers.define = function (Map, baseDefine) { + var definitions = Map.prototype.define; + if (baseDefine) { + var defines = {}; + mapHelpers.twoLevelDeepExtend(defines, baseDefine); + mapHelpers.twoLevelDeepExtend(defines, definitions); + extend(definitions, defines); + } + Map.defaultGenerators = {}; + for (var prop in definitions) { + var type = definitions[prop].type; + if (typeof type === 'string') { + if (typeof define.types[type] === 'object') { + delete definitions[prop].type; + extend(definitions[prop], define.types[type]); + } + } + if ('value' in definitions[prop]) { + if (typeof definitions[prop].value === 'function') { + Map.defaultGenerators[prop] = definitions[prop].value; + } else { + Map.defaults[prop] = definitions[prop].value; + } + } + if (typeof definitions[prop].Value === 'function') { + (function (Constructor) { + Map.defaultGenerators[prop] = function () { + return new Constructor(); + }; + }(definitions[prop].Value)); + } + } + }; + var oldSetupDefaults = CanMap.prototype._setupDefaults; + CanMap.prototype._setupDefaults = function (obj) { + var defaults = extend({}, oldSetupDefaults.call(this)), propsCommittedToAttr = {}, Map = this.constructor, originalGet = this._get; + this._get = function (originalProp) { + var prop = originalProp.indexOf('.') !== -1 ? originalProp.substr(0, originalProp.indexOf('.')) : originalProp; + if (prop in defaults && !(prop in propsCommittedToAttr)) { + this.attr(prop, defaults[prop]); + propsCommittedToAttr[prop] = true; + } + return originalGet.apply(this, arguments); + }; + for (var prop in Map.defaultGenerators) { + if (!obj || !(prop in obj)) { + defaults[prop] = Map.defaultGenerators[prop].call(this); + } + } + delete this._get; + return defaults; + }; + var proto = CanMap.prototype, oldSet = proto.__set; + proto.__set = function (prop, value, current, success, error) { + var self = this; + var errorCallback = function (errors) { + var stub = error && error.call(self, errors); + if (stub !== false) { + mapEventsMixin.dispatch.call(self, 'error', [ + prop, + errors + ], true); + } + return false; + }, setter = getPropDefineBehavior('set', prop, this.define), getter = getPropDefineBehavior('get', prop, this.define); + if (setter) { + queues.batch.start(); + var setterCalled = false, setValue = setter.call(this, value, function (value) { + if (getter) { + self[prop](value); + } else { + oldSet.call(self, prop, value, current, success, errorCallback); + } + setterCalled = true; + }, errorCallback, getter ? this._computedAttrs[prop].compute.computeInstance.lastSetValue.get() : current); + if (getter) { + if (setValue !== undefined && !setterCalled && setter.length >= 1) { + this._computedAttrs[prop].compute(setValue); + } + queues.batch.stop(); + return; + } else if (setValue === undefined && !setterCalled && setter.length > 1) { + queues.batch.stop(); + return; + } else { + if (!setterCalled) { + oldSet.call(self, prop, setter.length === 0 && setValue === undefined ? value : setValue, current, success, errorCallback); + } + queues.batch.stop(); + return this; + } + } else { + oldSet.call(self, prop, value, current, success, errorCallback); + } + return this; + }; + define.types = { + 'date': function (str) { + var type = typeof str; + if (type === 'string') { + str = Date.parse(str); + return isNaN(str) ? null : new Date(str); + } else if (type === 'number') { + return new Date(str); + } else { + return str; + } + }, + 'number': function (val) { + if (val == null) { + return val; + } + return +val; + }, + 'boolean': function (val) { + if (val == null) { + return val; + } + if (val === 'false' || val === '0' || !val) { + return false; + } + return true; + }, + 'htmlbool': function (val) { + return typeof val === 'string' || !!val; + }, + '*': function (val) { + return val; + }, + 'string': function (val) { + if (val == null) { + return val; + } + return '' + val; + }, + 'compute': { + set: function (newValue, setVal, setErr, oldValue) { + if (newValue && newValue.isComputed) { + return newValue; + } + if (oldValue && oldValue.isComputed) { + oldValue(newValue); + return oldValue; + } + return newValue; + }, + get: function (value) { + return value && value.isComputed ? value() : value; + } + } + }; + var oldType = proto.__type; + proto.__type = function (value, prop) { + var type = getPropDefineBehavior('type', prop, this.define), Type = getPropDefineBehavior('Type', prop, this.define), newValue = value; + if (typeof type === 'string') { + type = define.types[type]; + } + if (type || Type) { + if (type) { + newValue = type.call(this, newValue, prop); + } + if (Type && newValue != null && !(newValue instanceof Type)) { + newValue = new Type(newValue); + } + return newValue; + } else if (canReflect.isPlainObject(newValue) && newValue.define) { + newValue = CanMap.extend(newValue); + newValue = new newValue(); + } + return oldType.call(this, newValue, prop); + }; + var oldRemove = proto.__remove; + proto.__remove = function (prop, current) { + var remove = getPropDefineBehavior('remove', prop, this.define), res; + if (remove) { + queues.batch.start(); + res = remove.call(this, current); + if (res === false) { + queues.batch.stop(); + return; + } else { + res = oldRemove.call(this, prop, current); + queues.batch.stop(); + return res; + } + } + return oldRemove.call(this, prop, current); + }; + var oldSetupComputes = proto._setupComputedProperties; + proto._setupComputedProperties = function () { + oldSetupComputes.apply(this, arguments); + for (var attr in this.define) { + var def = this.define[attr], get = def.get; + if (get) { + mapHelpers.addComputedAttr(this, attr, compute.async(undefined, get, this)); + } + } + }; + var oldSingleSerialize = proto.___serialize; + var serializeProp = function (map, attr, val) { + var serializer = attr === '*' ? false : getPropDefineBehavior('serialize', attr, map.define); + if (serializer === undefined) { + return oldSingleSerialize.call(map, attr, val); + } else if (serializer !== false) { + return typeof serializer === 'function' ? serializer.call(map, val, attr) : oldSingleSerialize.call(map, attr, val); + } + }; + proto.___serialize = function (name, val) { + return serializeProp(this, name, val); + }; + var oldSerialize = proto.serialize; + proto.serialize = function (property) { + var serialized = oldSerialize.apply(this, arguments); + if (property) { + return serialized; + } + var serializer, val; + for (var attr in this.define) { + if (!(attr in serialized)) { + serializer = this.define && (this.define[attr] && this.define[attr].serialize || this.define['*'] && this.define['*'].serialize); + if (serializer) { + val = serializeProp(this, attr, this.attr(attr)); + if (val !== undefined) { + serialized[attr] = val; + } + } + } + } + return serialized; + }; + canReflect.assignSymbols(proto, { + 'can.hasKey': function (key) { + var defined = this.define && key in this.define; + var dataExists = this._data && key in this._data; + var propExists = key in this; + return defined || dataExists || propExists; + }, + 'can.getOwnEnumerableKeys': function () { + if (!this.__inSetup) { + ObservationRecorder.add(this, '__keys'); + } + var definedKeys = keysForDefinition(this.define); + var dataKeys = Object.keys(this._data); + var shouldSerialize = getDefaultForSerialize(this.define && this.define['*']); + var enumerable = this.constructor.enumerable; + dataKeys = dataKeys.filter(function (key) { + return enumerable ? shouldSerialize && enumerable[key] !== false : shouldSerialize; + }); + var i, newKey; + for (i = 0; i < dataKeys.length; i++) { + newKey = dataKeys[i]; + if (definedKeys.indexOf(newKey) < 0 && (!this.define || !this.define[newKey])) { + definedKeys.push(dataKeys[i]); + } + } + return definedKeys; + } + }); + module.exports = define; +}); +/*can-map-define@4.3.4#can-map-define_test*/ +define('can-map-define@4.3.4#can-map-define_test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-key/sub/sub', + 'can-map', + 'can-list', + 'can-compute', + 'can-reflect', + './can-map-define', + 'can-reflect-tests/observables/map-like/type/type' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var sub = require('can-key/sub/sub'); + var CanMap = require('can-map'); + var List = require('can-list'); + var compute = require('can-compute'); + var canReflect = require('can-reflect'); + require('./can-map-define'); + QUnit.module('can-map-define'); + QUnit.test('basics set', function () { + var Defined = CanMap.extend({ + define: { + prop: { + set: function (newVal) { + return 'foo' + newVal; + } + } + } + }); + var def = new Defined(); + def.attr('prop', 'bar'); + equal(def.attr('prop'), 'foobar', 'setter works'); + Defined = CanMap.extend({ + define: { + prop: { + set: function (newVal, setter) { + setter('foo' + newVal); + } + } + } + }); + def = new Defined(); + def.attr('prop', 'bar'); + equal(def.attr('prop'), 'foobar', 'setter callback works'); + }); + QUnit.test('basics remove', function () { + var ViewModel = CanMap.extend({ + define: { + makeId: { + remove: function () { + this.removeAttr('models'); + } + }, + models: { + remove: function () { + this.removeAttr('modelId'); + } + }, + modelId: { + remove: function () { + this.removeAttr('years'); + } + }, + years: { + remove: function () { + this.removeAttr('year'); + } + } + } + }); + var mmy = new ViewModel({ + makes: [{ id: 1 }], + makeId: 1, + models: [{ id: 2 }], + modelId: 2, + years: [2010], + year: 2010 + }); + var events = [ + 'year', + 'years', + 'modelId', + 'models', + 'makeId' + ], eventCount = 0, batchNum; + mmy.bind('change', function (ev, attr) { + if (batchNum === undefined) { + batchNum = ev.batchNum; + } + equal(attr, events[eventCount++], 'got correct attribute'); + ok(ev.batchNum && ev.batchNum === batchNum, 'batched'); + }); + mmy.removeAttr('makeId'); + }); + QUnit.test('basics get', function (assert) { + var done = assert.async(); + var Person = CanMap.extend({ + define: { + fullName: { + get: function () { + return this.attr('first') + ' ' + this.attr('last'); + } + } + } + }); + var p = new Person({ + first: 'Justin', + last: 'Meyer' + }); + assert.equal(p.attr('fullName'), 'Justin Meyer', 'sync getter works'); + var Adder = CanMap.extend({ + define: { + more: { + get: function (curVal, setVal) { + var num = this.attr('num'); + setTimeout(function () { + setVal(num + 1); + }, 10); + } + } + } + }); + var callbackCount = 0; + var a = new Adder({ num: 1 }); + var callbackVals = [ + { + newVal: 2, + oldVal: undefined, + next: function next() { + a.attr('num', 2); + } + }, + { + newVal: 3, + oldVal: 2, + next: done + } + ]; + a.bind('more', function (ev, newVal, oldVal) { + var vals = callbackVals[callbackCount++]; + assert.equal(newVal, vals.newVal, 'newVal is correct'); + assert.equal(a.attr('more'), vals.newVal, 'attr value is correct'); + assert.equal(oldVal, vals.oldVal, 'oldVal is correct'); + setTimeout(vals.next, 10); + }); + }); + QUnit.test('basic type', function () { + expect(6); + var Typer = CanMap.extend({ + define: { + arrayWithAddedItem: { + type: function (value) { + if (value && value.push) { + value.push('item'); + } + return value; + } + }, + listWithAddedItem: { + type: function (value) { + if (value && value.push) { + value.push('item'); + } + return value; + }, + Type: List + } + } + }); + var t = new Typer(); + deepEqual(CanMap.keys(t), [ + 'arrayWithAddedItem', + 'listWithAddedItem' + ], 'defined keys'); + var array = []; + t.attr('arrayWithAddedItem', array); + deepEqual(array, ['item'], 'updated array'); + equal(t.attr('arrayWithAddedItem'), array, 'leave value as array'); + t.attr('listWithAddedItem', []); + ok(t.attr('listWithAddedItem') instanceof List, 'convert to List'); + equal(t.attr('listWithAddedItem').attr(0), 'item', 'has item in it'); + t.bind('change', function (ev, attr) { + equal(attr, 'listWithAddedItem.1', 'got a bubbling event'); + }); + t.attr('listWithAddedItem').push('another item'); + }); + QUnit.test('basic Type', function () { + var Foo = function (name) { + this.name = name; + }; + Foo.prototype.getName = function () { + return this.name; + }; + var Typer = CanMap.extend({ define: { foo: { Type: Foo } } }); + var t = new Typer({ foo: 'Justin' }); + equal(t.attr('foo').getName(), 'Justin', 'correctly created an instance'); + var brian = new Foo('brian'); + t.attr('foo', brian); + equal(t.attr('foo'), brian, 'same instances'); + }); + QUnit.test('type converters', function () { + var Typer = CanMap.extend({ + define: { + date: { type: 'date' }, + string: { type: 'string' }, + number: { type: 'number' }, + 'boolean': { type: 'boolean' }, + htmlbool: { type: 'htmlbool' }, + leaveAlone: { type: '*' } + } + }); + var obj = {}; + var t = new Typer({ + date: 1395896701516, + string: 5, + number: '5', + 'boolean': 'false', + htmlbool: '', + leaveAlone: obj + }); + ok(t.attr('date') instanceof Date, 'converted to date'); + equal(t.attr('string'), '5', 'converted to string'); + equal(t.attr('number'), 5, 'converted to number'); + equal(t.attr('boolean'), false, 'converted to boolean'); + equal(t.attr('htmlbool'), true, 'converted to htmlbool'); + equal(t.attr('leaveAlone'), obj, 'left as object'); + t.attr({ 'number': '15' }); + ok(t.attr('number') === 15, 'converted to number'); + }); + QUnit.test('basics value', function () { + var Typer = CanMap.extend({ define: { prop: { value: 'foo' } } }); + equal(new Typer().attr('prop'), 'foo', 'value is used as default value'); + var Typer2 = CanMap.extend({ + define: { + prop: { + value: function () { + return []; + }, + type: '*' + } + } + }); + var t1 = new Typer2(), t2 = new Typer2(); + ok(t1.attr('prop') !== t2.attr('prop'), 'different array instances'); + ok(Array.isArray(t1.attr('prop')), 'its an array'); + }); + QUnit.test('basics Value', function () { + var Typer = CanMap.extend({ + define: { + prop: { + Value: Array, + type: '*' + } + } + }); + var t1 = new Typer(), t2 = new Typer(); + ok(t1.attr('prop') !== t2.attr('prop'), 'different array instances'); + ok(Array.isArray(t1.attr('prop')), 'its an array'); + }); + QUnit.test('setter with no arguments and returns undefined does the default behavior, the setter is for side effects only', function () { + var Typer = CanMap.extend({ + define: { + prop: { + set: function () { + this.attr('foo', 'bar'); + } + } + } + }); + var t = new Typer(); + t.attr('prop', false); + deepEqual(t.attr(), { + foo: 'bar', + prop: false + }); + }); + QUnit.test('type happens before the set', function () { + var MyMap = CanMap.extend({ + define: { + prop: { + type: 'number', + set: function (newValue) { + equal(typeof newValue, 'number', 'got a number'); + return newValue + 1; + } + } + } + }); + var map = new MyMap(); + map.attr('prop', '5'); + equal(map.attr('prop'), 6, 'number'); + }); + QUnit.test('getter and setter work', function () { + expect(5); + var Paginate = CanMap.extend({ + define: { + page: { + set: function (newVal) { + this.attr('offset', (parseInt(newVal) - 1) * this.attr('limit')); + }, + get: function () { + return Math.floor(this.attr('offset') / this.attr('limit')) + 1; + } + } + } + }); + var p = new Paginate({ + limit: 10, + offset: 20 + }); + equal(p.attr('page'), 3, 'page get right'); + p.bind('page', function (ev, newValue, oldValue) { + equal(newValue, 2, 'got new value event'); + equal(oldValue, 3, 'got old value event'); + }); + p.attr('page', 2); + equal(p.attr('page'), 2, 'page set right'); + equal(p.attr('offset'), 10, 'page offset set'); + }); + QUnit.test('getter with initial value', function () { + var comp = compute(1); + var Grabber = CanMap.extend({ + define: { + vals: { + type: '*', + Value: Array, + get: function (current, setVal) { + if (setVal) { + current.push(comp()); + } + return current; + } + } + } + }); + var g = new Grabber(); + equal(g.attr('vals').length, 0, 'zero items in array'); + }); + QUnit.test('serialize basics', function () { + var MyMap = CanMap.extend({ + define: { + name: { + serialize: function () { + return; + } + }, + locations: { serialize: false }, + locationIds: { + get: function () { + var ids = []; + this.attr('locations').forEach(function (location) { + ids.push(location.id); + }); + return ids; + }, + serialize: function (locationIds) { + return locationIds.join(','); + } + }, + bared: { + get: function () { + return this.attr('name') + '+bar'; + }, + serialize: true + }, + ignored: { + get: function () { + return this.attr('name') + '+ignored'; + } + } + } + }); + var map = new MyMap({ name: 'foo' }); + map.attr('locations', [ + { + id: 1, + name: 'Chicago' + }, + { + id: 2, + name: 'LA' + } + ]); + equal(map.attr('locationIds').length, 2, 'get locationIds'); + equal(map.attr('locationIds')[0], 1, 'get locationIds index 0'); + equal(map.attr('locations')[0].id, 1, 'get locations index 0'); + var serialized = map.serialize(); + equal(serialized.locations, undefined, 'locations doesn\'t serialize'); + equal(serialized.locationIds, '1,2', 'locationIds serializes'); + equal(serialized.name, undefined, 'name doesn\'t serialize'); + equal(serialized.bared, 'foo+bar', 'true adds computed props'); + equal(serialized.ignored, undefined, 'computed props are not serialized by default'); + }); + QUnit.test('serialize context', function () { + var context, serializeContext; + var MyMap = CanMap.extend({ + define: { + name: { + serialize: function (obj) { + context = this; + return obj; + } + } + }, + serialize: function () { + serializeContext = this; + CanMap.prototype.serialize.apply(this, arguments); + } + }); + var map = new MyMap(); + map.serialize(); + equal(context, map); + equal(serializeContext, map); + }); + QUnit.test('methods contexts', function () { + var contexts = {}; + var MyMap = CanMap.extend({ + define: { + name: { + value: 'John Galt', + get: function (obj) { + contexts.get = this; + return obj; + }, + remove: function (obj) { + contexts.remove = this; + return obj; + }, + set: function (obj) { + contexts.set = this; + return obj; + }, + serialize: function (obj) { + contexts.serialize = this; + return obj; + }, + type: function (val) { + contexts.type = this; + return val; + } + } + } + }); + var map = new MyMap(); + map.serialize(); + map.removeAttr('name'); + equal(contexts.get, map); + equal(contexts.remove, map); + equal(contexts.set, map); + equal(contexts.serialize, map); + equal(contexts.type, map); + }); + QUnit.test('value generator is not called if default passed', function () { + var TestMap = CanMap.extend({ + define: { + foo: { + value: function () { + throw '"foo"\'s value method should not be called.'; + } + } + } + }); + var tm = new TestMap({ foo: 'baz' }); + equal(tm.attr('foo'), 'baz'); + }); + QUnit.test('Value generator can read other properties', function () { + var Map = CanMap.extend({ + letters: 'ABC', + numbers: [ + 1, + 2, + 3 + ], + define: { + definedLetters: { value: 'DEF' }, + definedNumbers: { + value: [ + 4, + 5, + 6 + ] + }, + generatedLetters: { + value: function () { + return 'GHI'; + } + }, + generatedNumbers: { + value: function () { + return new List([ + 7, + 8, + 9 + ]); + } + }, + firstLetter: { + value: function () { + return this.attr('letters').substr(0, 1); + } + }, + firstNumber: { + value: function () { + return this.attr('numbers.0'); + } + }, + middleLetter: { + value: function () { + return this.attr('definedLetters').substr(1, 1); + } + }, + middleNumber: { + value: function () { + return this.attr('definedNumbers.1'); + } + }, + lastLetter: { + value: function () { + return this.attr('generatedLetters').substr(2, 1); + } + }, + lastNumber: { + value: function () { + return this.attr('generatedNumbers.2'); + } + } + } + }); + var map = new Map(); + var prefix = 'Was able to read dependent value from '; + equal(map.attr('firstLetter'), 'A', prefix + 'traditional CanMap style property definition'); + equal(map.attr('firstNumber'), 1, prefix + 'traditional CanMap style property definition'); + equal(map.attr('middleLetter'), 'E', prefix + 'define plugin style default property definition'); + equal(map.attr('middleNumber'), 5, prefix + 'define plugin style default property definition'); + equal(map.attr('lastLetter'), 'I', prefix + 'define plugin style generated default property definition'); + equal(map.attr('lastNumber'), 9, prefix + 'define plugin style generated default property definition'); + }); + QUnit.test('default behaviors with "*" work for attributes', function () { + expect(9); + var DefaultMap = CanMap.extend({ + define: { + someNumber: { value: '5' }, + '*': { + type: 'number', + serialize: function (value) { + return '' + value; + }, + set: function (newVal) { + ok(true, 'set called'); + return newVal; + }, + remove: function (currentVal) { + ok(true, 'remove called'); + return false; + } + } + } + }); + var map = new DefaultMap(), serializedMap; + equal(map.attr('someNumber'), 5, 'value of someNumber should be converted to a number'); + map.attr('number', '10'); + equal(map.attr('number'), 10, 'value of number should be converted to a number'); + map.removeAttr('number'); + equal(map.attr('number'), 10, 'number should not be removed'); + serializedMap = map.serialize(); + equal(serializedMap.number, '10', 'number serialized as string'); + equal(serializedMap.someNumber, '5', 'someNumber serialized as string'); + equal(serializedMap['*'], undefined, '"*" is not a value in serialized object'); + }); + QUnit.test('models properly serialize with default behaviors', function () { + var DefaultMap = CanMap.extend({ + define: { + name: { value: 'Alex' }, + shirt: { + value: 'blue', + serialize: true + }, + '*': { serialize: false } + } + }); + var map = new DefaultMap({ + age: 10, + name: 'John' + }), serializedMap = map.serialize(); + equal(serializedMap.age, undefined, 'age doesn\'t exist'); + equal(serializedMap.name, undefined, 'name doesn\'t exist'); + equal(serializedMap.shirt, 'blue', 'shirt exists'); + }); + QUnit.test('nested define', function () { + var nailedIt = 'Nailed it'; + var Example = CanMap.extend({}, { define: { name: { value: nailedIt } } }); + var NestedMap = CanMap.extend({}, { + define: { + isEnabled: { value: true }, + test: { Value: Example }, + examples: { + value: { + define: { + one: { Value: Example }, + two: { value: { define: { deep: { Value: Example } } } } + } + } + } + } + }); + var nested = new NestedMap(); + equal(nested.attr('test.name'), nailedIt); + equal(nested.attr('examples.one.name'), nailedIt); + equal(nested.attr('examples.two.deep.name'), nailedIt); + ok(nested.attr('test') instanceof Example); + ok(nested.attr('examples.one') instanceof Example); + ok(nested.attr('examples.two.deep') instanceof Example); + }); + QUnit.test('Can make an attr alias a compute (#1470)', 9, function () { + var computeValue = compute(1); + var GetMap = CanMap.extend({ + define: { + value: { + set: function (newValue, setVal, setErr, oldValue) { + if (newValue.isComputed) { + return newValue; + } + if (oldValue && oldValue.isComputed) { + oldValue(newValue); + return oldValue; + } + return newValue; + }, + get: function (value) { + return value && value.isComputed ? value() : value; + } + } + } + }); + var getMap = new GetMap(); + getMap.attr('value', computeValue); + equal(getMap.attr('value'), 1); + var bindCallbacks = 0; + getMap.bind('value', function (ev, newVal, oldVal) { + switch (bindCallbacks) { + case 0: + equal(newVal, 2, '0 - bind called with new val'); + equal(oldVal, 1, '0 - bind called with old val'); + break; + case 1: + equal(newVal, 3, '1 - bind called with new val'); + equal(oldVal, 2, '1 - bind called with old val'); + break; + case 2: + equal(newVal, 4, '2 - bind called with new val'); + equal(oldVal, 3, '2 - bind called with old val'); + break; + } + bindCallbacks++; + }); + computeValue(2); + getMap.attr('value', 3); + equal(getMap.attr('value'), 3, 'read value is 3'); + equal(computeValue(), 3, 'the compute value is 3'); + var newComputeValue = compute(4); + getMap.attr('value', newComputeValue); + }); + QUnit.test('setting a value of a property with type "compute" triggers change events', function () { + var handler; + var message = 'The change event passed the correct {prop} when set with {method}'; + var createChangeHandler = function (expectedOldVal, expectedNewVal, method) { + return function (ev, newVal, oldVal) { + var subs = { + prop: 'newVal', + method: method + }; + equal(newVal, expectedNewVal, sub(message, subs)); + subs.prop = 'oldVal'; + equal(oldVal, expectedOldVal, sub(message, subs)); + }; + }; + var ComputableMap = CanMap.extend({ define: { computed: { type: 'compute' } } }); + var computed = compute(0); + var m1 = new ComputableMap({ computed: computed }); + equal(m1.attr('computed'), 0, 'm1 is 1'); + handler = createChangeHandler(0, 1, '.attr(\'computed\', newVal)'); + m1.bind('computed', handler); + m1.attr('computed', 1); + m1.unbind('computed', handler); + handler = createChangeHandler(1, 2, 'computed()'); + m1.bind('computed', handler); + computed(2); + m1.unbind('computed', handler); + }); + QUnit.test('replacing the compute on a property with type "compute"', function () { + var compute1 = compute(0); + var compute2 = compute(1); + var ComputableMap = CanMap.extend({ define: { computable: { type: 'compute' } } }); + var m = new ComputableMap(); + m.attr('computable', compute1); + equal(m.attr('computable'), 0, 'compute1 readable via .attr()'); + m.attr('computable', compute2); + equal(m.attr('computable'), 1, 'compute2 readable via .attr()'); + }); + QUnit.test('value and get (#1521)', function () { + var MyMap = CanMap.extend({ + define: { + data: { + value: function () { + return new List(['test']); + } + }, + size: { + value: 1, + get: function (val) { + var list = this.attr('data'); + var length = list.attr('length'); + return val + length; + } + } + } + }); + var map = new MyMap({}); + equal(map.attr('size'), 2); + }); + QUnit.test('One event on getters (#1585)', function () { + var AppState = CanMap.extend({ + define: { + person: { + get: function (lastSetValue, setAttrValue) { + if (lastSetValue) { + return lastSetValue; + } else if (this.attr('personId')) { + setAttrValue(new CanMap({ + name: 'Jose', + id: 5 + })); + } else { + return null; + } + } + } + } + }); + var appState = new AppState(); + var personEvents = 0; + appState.bind('person', function (ev, person) { + personEvents++; + }); + appState.attr('personId', 5); + appState.attr('person', new CanMap({ name: 'Julia' })); + equal(personEvents, 2); + }); + QUnit.test('Can read a defined property with a set/get method (#1648)', function () { + var Map = CanMap.extend({ + define: { + foo: { + value: '', + set: function (setVal) { + return setVal; + }, + get: function (lastSetVal) { + return lastSetVal; + } + } + } + }); + var map = new Map(); + equal(map.attr('foo'), '', 'Calling .attr(\'foo\') returned the correct value'); + map.attr('foo', 'baz'); + equal(map.attr('foo'), 'baz', 'Calling .attr(\'foo\') returned the correct value'); + }); + QUnit.test('Can bind to a defined property with a set/get method (#1648)', 3, function () { + var Map = CanMap.extend({ + define: { + foo: { + value: '', + set: function (setVal) { + return setVal; + }, + get: function (lastSetVal) { + return lastSetVal; + } + } + } + }); + var map = new Map(); + map.bind('foo', function () { + ok(true, 'Bound function is called'); + }); + equal(map.attr('foo'), '', 'Calling .attr(\'foo\') returned the correct value'); + map.attr('foo', 'baz'); + equal(map.attr('foo'), 'baz', 'Calling .attr(\'foo\') returned the correct value'); + }); + QUnit.test('type converters handle null and undefined in expected ways (1693)', function () { + var Typer = CanMap.extend({ + define: { + date: { + type: 'date', + value: 'Mon Jul 30 2018 11:57:14 GMT-0500 (Central Daylight Time)' + }, + string: { + type: 'string', + value: 'mudd' + }, + number: { + type: 'number', + value: 42 + }, + 'boolean': { + type: 'boolean', + value: false + }, + htmlbool: { + type: 'htmlbool', + value: true + }, + leaveAlone: { type: '*' } + } + }); + var t = new Typer().attr({ + date: undefined, + string: undefined, + number: undefined, + 'boolean': undefined, + htmlbool: undefined, + leaveAlone: undefined + }); + equal(t.attr('date'), undefined, 'converted to date'); + equal(t.attr('string'), undefined, 'converted to string'); + equal(t.attr('number'), undefined, 'converted to number'); + equal(t.attr('boolean'), undefined, 'converted to boolean'); + equal(t.attr('htmlbool'), false, 'converted to htmlbool'); + equal(t.attr('leaveAlone'), undefined, 'left as object'); + t = new Typer().attr({ + date: null, + string: null, + number: null, + 'boolean': null, + htmlbool: null, + leaveAlone: null + }); + equal(t.attr('date'), null, 'converted to date'); + equal(t.attr('string'), null, 'converted to string'); + equal(t.attr('number'), null, 'converted to number'); + equal(t.attr('boolean'), null, 'converted to boolean'); + equal(t.attr('htmlbool'), false, 'converted to htmlbool'); + equal(t.attr('leaveAlone'), null, 'left as object'); + }); + QUnit.test('Initial value does not call getter', function () { + expect(0); + var Map = CanMap.extend({ + define: { + count: { + get: function (lastVal) { + ok(false, 'Should not be called'); + return lastVal; + } + } + } + }); + new Map({ count: 100 }); + }); + QUnit.test('getters produce change events', function () { + var Map = CanMap.extend({ + define: { + count: { + get: function (lastVal) { + return lastVal; + } + } + } + }); + var map = new Map(); + map.bind('change', function () { + ok(true, 'change called'); + }); + map.attr('count', 22); + }); + QUnit.test('Asynchronous virtual properties cause extra recomputes (#1915)', function () { + stop(); + var ran = false; + var VM = CanMap.extend({ + define: { + foo: { + get: function (lastVal, setVal) { + setTimeout(function () { + if (setVal) { + setVal(5); + } + }, 10); + } + }, + bar: { + get: function () { + var foo = this.attr('foo'); + if (foo) { + if (ran) { + ok(false, 'Getter ran twice'); + } + ran = true; + return foo * 2; + } + } + } + } + }); + var vm = new VM(); + vm.bind('bar', function () { + }); + setTimeout(function () { + equal(vm.attr('bar'), 10); + start(); + }, 200); + }); + QUnit.test('double get in a compute (#2230)', function () { + var VM = CanMap.extend({ + define: { + names: { + get: function (val, setVal) { + ok(setVal, 'setVal passed'); + return 'Hi!'; + } + } + } + }); + var vm = new VM(); + var c = compute(function () { + return vm.attr('names'); + }); + c.bind('change', function () { + }); + }); + QUnit.test('nullish values are not converted for Type', function (assert) { + var VM = CanMap.extend({ + define: { + map: { Type: CanMap }, + notype: {} + } + }); + var vm = new VM({ + num: 1, + bool: true, + htmlbool: 'foo', + str: 'foo', + date: Date.now(), + map: {}, + notype: {} + }); + assert.ok(vm.attr('map') instanceof CanMap, 'map is a Map'); + assert.ok(vm.attr('notype') instanceof CanMap, 'notype is a Map'); + vm.attr({ + map: null, + notype: null + }); + assert.equal(vm.attr('map'), null, 'map is null'); + assert.equal(vm.attr('map'), null, 'notype is null'); + }); + QUnit.test('Wildcard serialize doesn\'t apply to getter properties (#4)', function () { + var VM = CanMap.extend({ + define: { + explicitlySerialized: { + get: function () { + return true; + }, + serialize: true + }, + implicitlySerialized: { + get: function () { + return true; + } + }, + '*': { serialize: true } + } + }); + var vm = new VM(); + vm.bind('change', function () { + }); + deepEqual(vm.serialize(), { + explicitlySerialized: true, + implicitlySerialized: true + }); + }); + QUnit.test('compute props can be set to null or undefined (#2372)', function (assert) { + var VM = CanMap.extend({ define: { foo: { type: 'compute' } } }); + var vmNull = new VM({ foo: null }); + assert.equal(vmNull.foo, null, 'foo is null, no error thrown'); + var vmUndef = new VM({ foo: undefined }); + assert.equal(vmUndef.foo, undefined, 'foo is null, no error thrown'); + }); + QUnit.test('can inherit computes from another map (#2)', 4, function () { + var string1 = 'a string'; + var string2 = 'another string'; + var MapA = CanMap.extend({ + define: { + propA: { + get: function () { + return string1; + } + }, + propB: { + get: function () { + return string1; + }, + set: function (newVal) { + equal(newVal, string1, 'set was called'); + } + } + } + }); + var MapB = MapA.extend({ + define: { + propC: { + get: function () { + return string2; + } + }, + propB: { + get: function () { + return string2; + } + } + } + }); + var map = new MapB(); + equal(map.attr('propC'), string2, 'props only in the child have the correct values'); + equal(map.attr('propB'), string2, 'props in both have the child values'); + equal(map.attr('propA'), string1, 'props only in the parent have the correct values'); + map.attr('propB', string1); + }); + QUnit.test('can inherit primitive values from another map (#2)', function () { + var string1 = 'a'; + var string2 = 'b'; + var MapA = CanMap.extend({ + define: { + propA: { value: string1 }, + propB: { value: string1 } + } + }); + var MapB = MapA.extend({ + define: { + propC: { value: string2 }, + propB: { value: string2 } + } + }); + var map = new MapB(); + equal(map.propC, string2, 'props only in the child have the correct values'); + equal(map.propB, string2, 'props in both have the child values'); + equal(map.propA, string1, 'props only in the parent have the correct values'); + }); + QUnit.test('can inherit object values from another map (#2)', function () { + var object1 = { a: 'a' }; + var object2 = { b: 'b' }; + var MapA = CanMap.extend({ + define: { + propA: { + get: function () { + return object1; + } + }, + propB: { + get: function () { + return object1; + } + } + } + }); + var MapB = MapA.extend({ + define: { + propB: { + get: function () { + return object2; + } + }, + propC: { + get: function () { + return object2; + } + } + } + }); + var map = new MapB(); + equal(map.attr('propC'), object2, 'props only in the child have the correct values'); + equal(map.attr('propB'), object2, 'props in both have the child values'); + equal(map.attr('propA'), object1, 'props only in the parent have the correct values'); + }); + QUnit.test('can set properties to undefined', function () { + var MyMap = CanMap.extend({ + define: { + foo: { + set: function (newVal) { + return newVal; + } + } + } + }); + var map = new MyMap(); + map.attr('foo', 'bar'); + equal(map.attr('foo'), 'bar', 'foo should be bar'); + map.attr('foo', undefined); + equal(typeof map.attr('foo'), 'undefined', 'foo should be undefined'); + }); + QUnit.test('subclass defines do not affect superclass ones', function (assert) { + var VM = CanMap.extend({ + define: { + foo: { + type: 'string', + value: 'bar' + } + } + }); + var VM2 = VM.extend({ define: { foo: { value: 'baz' } } }); + var VM2a = VM.extend({}); + var VM2b = VM.extend({ + define: { + foo: { + get: function () { + return 'quux'; + } + } + } + }); + var VM2c = VM.extend({ + define: { + foo: { + type: function (oldVal) { + return oldVal + 'thud'; + } + } + } + }); + assert.equal(new VM().attr('foo'), 'bar', 'correct define on parent class object'); + assert.equal(new VM2().attr('foo'), 'baz', 'correct define on redefined child class object'); + assert.equal(new VM2a().attr('foo'), 'bar', 'correct define on non-redefined child class object'); + assert.equal(new VM2b().attr('foo'), 'quux', 'correct define on child class object with different define'); + assert.equal(new VM2c().attr('foo'), 'barthud', 'correct define on child class object with extending define'); + }); + QUnit.test('value function not set on constructor defaults', function () { + var MyMap = CanMap.extend({ + define: { + propA: { + value: function () { + return 1; + } + } + } + }); + var map = new MyMap(); + equal(MyMap.defaults.propA, undefined, 'Generator function does not result in property set on defaults'); + notEqual(MyMap.defaultGenerators.propA, undefined, 'Generator function set on defaultGenerators'); + equal(map.attr('propA'), 1, 'Instance value set properly'); + }); + QUnit.test('can.hasKey', function () { + var Parent = CanMap.extend({ + define: { + parentProp: { type: '*' }, + parentDerivedProp: { + get: function () { + if (this.parentProp) { + return 'parentDerived'; + } + } + } + }, + parentFunction: function () { + return 'parentFunction return value'; + } + }); + var VM = Parent.extend({ + define: { + prop: { type: '*' }, + derivedProp: { + get: function () { + if (this.prop) { + return 'derived'; + } + } + } + }, + aFunction: function () { + return 'aFunction return value'; + } + }); + var vm = new VM(); + equal(canReflect.hasKey(vm, 'prop'), true, 'vm.hasKey(\'prop\') true'); + equal(canReflect.hasKey(vm, 'derivedProp'), true, 'vm.hasKey(\'derivedProp\') true'); + equal(canReflect.hasKey(vm, 'parentProp'), true, 'vm.hasKey(\'parentProp\') true'); + equal(canReflect.hasKey(vm, 'parentDerivedProp'), true, 'vm.hasKey(\'parentDerivedProp\') true'); + equal(canReflect.hasKey(vm, 'anotherProp'), false, 'vm.hasKey(\'anotherProp\') false'); + equal(canReflect.hasKey(vm, 'aFunction'), true, 'vm.hasKey(\'aFunction\') true'); + equal(canReflect.hasKey(vm, 'parentFunction'), true, 'vm.hasKey(\'parentFunction\') true'); + vm.attr('lateProp', 'something'); + equal(canReflect.hasKey(vm, 'lateProp'), true, 'vm.hasKey(\'lateProp\') true'); + }); + QUnit.test('can.getOwnEnumerableKeys', function () { + var ParentMap = CanMap.extend({ + define: { + parentNoEnum: { + serialize: false, + value: 'parent_no' + }, + parentEnum: { + serialize: true, + value: 'parent_yes' + }, + parentEnumByDefault: { value: 'maybe' }, + parentEnumGetter: { + get: function () { + return 'parent_get'; + } + } + } + }); + var VM = ParentMap.extend({ + define: { + notEnumerable: { + serialize: false, + value: 'no' + }, + enumerableProp: { + serialize: true, + value: 'yes' + }, + enumByDefault: { value: 'maybe' }, + enumGetter: { + get: function () { + return 'got'; + } + } + } + }); + var vm = new VM(); + deepEqual(canReflect.getOwnEnumerableKeys(vm), [ + 'enumerableProp', + 'enumByDefault', + 'parentEnum', + 'parentEnumByDefault' + ], 'vm.getOwnEnumerableKeys()'); + vm.attr('lateProp', true); + deepEqual(canReflect.getOwnEnumerableKeys(vm), [ + 'enumerableProp', + 'enumByDefault', + 'parentEnum', + 'parentEnumByDefault', + 'lateProp' + ], 'vm.getOwnEnumerableKeys() with late prop'); + }); + QUnit.test('can.getOwnEnumerableKeys works without define (#81)', function () { + var VM = CanMap.extend({}); + var vm = new VM({ foo: 'bar' }); + deepEqual(canReflect.getOwnEnumerableKeys(vm), ['foo'], 'without define'); + vm.attr('abc', 'xyz'); + deepEqual(canReflect.getOwnEnumerableKeys(vm), [ + 'foo', + 'abc' + ], 'without define, with late prop'); + VM = CanMap.extend({ define: {} }); + vm = new VM({ foo: 'bar' }); + deepEqual(canReflect.getOwnEnumerableKeys(vm), ['foo'], 'with empty define'); + vm.attr('abc', 'xyz'); + deepEqual(canReflect.getOwnEnumerableKeys(vm), [ + 'foo', + 'abc' + ], 'with empty define, with late prop'); + }); + QUnit.test('can.getOwnEnumerableKeys works with null', function () { + var VM = CanMap.extend({}); + var vm = new VM({ foo: null }); + deepEqual(canReflect.getOwnEnumerableKeys(vm), ['foo'], 'getOwnEnumerableKeys works with null'); + }); + require('can-reflect-tests/observables/map-like/type/type')('CanMap / can-map-define', function () { + return CanMap.extend({}); + }); + QUnit.test('can.getOwnEnumerableKeys with default behavior', function (assert) { + var VM = CanMap.extend({ + define: { + '*': { serialize: false }, + notEnumerable: { value: 'no' }, + enumerableProp: { + serialize: true, + value: 'yes' + }, + notEnumerable2: { + serialize: false, + value: 'maybe' + }, + enumGetter: { + get: function () { + return 'got'; + } + } + } + }); + var vm = new VM(); + assert.deepEqual(canReflect.getOwnEnumerableKeys(vm), ['enumerableProp'], 'vm.getOwnEnumerableKeys()'); + }); + QUnit.test('can.getOwnEnumerableKeys with default behavior and late set properties', function (assert) { + var VM = CanMap.extend({ + define: { + '*': { serialize: false }, + notEnumerable: { value: 'no' }, + enumerableProp: { + serialize: true, + value: 'yes' + } + } + }); + var vm = new VM(); + assert.deepEqual(canReflect.getOwnEnumerableKeys(vm), ['enumerableProp'], 'getOwnEnumerableKeys() should return explicitly serializable properties'); + vm.attr('lateProperty', true); + assert.deepEqual(canReflect.getOwnEnumerableKeys(vm), ['enumerableProp'], 'late set properties should inherit default behavior'); + }); + QUnit.test('can.getOwnEnumerableKeys with default behavior, nested maps and late set props', function (assert) { + var ParentMap = CanMap.extend({ + define: { + parentNoEnum: { + serialize: false, + value: 'parent_no' + }, + parentEnum: { + serialize: true, + value: 'parent_yes' + }, + parentEnumByDefault: { value: 'maybe' }, + parentEnumGetter: { + get: function () { + return 'parent_get'; + } + } + } + }); + var VM = ParentMap.extend({ + define: { + '*': { serialize: false }, + notEnumerable: { + serialize: false, + value: 'no' + }, + enumerableProp: { + serialize: true, + value: 'yes' + }, + alsoNotEnumerable: { value: 'maybe' }, + enumGetter: { + get: function () { + return 'got'; + } + } + } + }); + var vm = new VM(); + assert.deepEqual(canReflect.getOwnEnumerableKeys(vm), [ + 'enumerableProp', + 'parentEnum' + ], 'vm.getOwnEnumerableKeys()'); + vm.attr('lateProperty', true); + assert.deepEqual(canReflect.getOwnEnumerableKeys(vm), [ + 'enumerableProp', + 'parentEnum' + ], 'late added properties should inherit default behavior'); + }); +}); +/*can-fixture@3.0.4#data-from-url*/ +define('can-fixture@3.0.4#data-from-url', function (require, exports, module) { + var replacer = /\{([^\}]+)\}/g; + module.exports = function dataFromUrl(fixtureUrl, url) { + if (!fixtureUrl) { + return {}; + } + var order = [], fixtureUrlAdjusted = fixtureUrl.replace('.', '\\.').replace('?', '\\?'), res = new RegExp(fixtureUrlAdjusted.replace(replacer, function (whole, part) { + order.push(part); + return '([^/]+)'; + }) + '$').exec(url), data = {}; + if (!res) { + return null; + } + res.shift(); + order.forEach(function (name) { + data[name] = res.shift(); + }); + return data; + }; +}); +/*can-fixture@3.0.4#matches*/ +define('can-fixture@3.0.4#matches', [ + 'require', + 'exports', + 'module', + 'can-query-logic/src/set', + 'can-reflect', + './data-from-url', + 'can-query-logic' +], function (require, exports, module) { + var set = require('can-query-logic/src/set'); + var canReflect = require('can-reflect'); + var dataFromUrl = require('./data-from-url'); + var QueryLogic = require('can-query-logic'); + function deepEqual(a, b) { + if (a === b) { + return true; + } else if (Array.isArray(a) && Array.isArray(b)) { + if (a.length !== b.length) { + return false; + } else { + return a.every(function (aVal, i) { + return deepEqual(aVal, b[i]); + }); + } + } else if (a && b && canReflect.isPlainObject(a) && canReflect.isPlainObject(b)) { + var aKeys = Object.keys(a), bKeys = Object.keys(b); + if (aKeys.length === bKeys.length) { + for (var prop in a) { + if (!b.hasOwnProperty(prop)) { + return false; + } + if (!deepEqual(a[prop], b[prop])) { + return false; + } + } + return true; + } else { + return false; + } + } else { + return false; + } + } + function deepMatches(a, b) { + if (a === b) { + return true; + } else if (Array.isArray(a) && Array.isArray(b)) { + return a.every(function (aVal, i) { + return deepMatches(aVal, b[i]); + }); + } else if (a && b && canReflect.isPlainObject(a) && canReflect.isPlainObject(b)) { + for (var prop in a) { + if (!b.hasOwnProperty(prop)) { + return false; + } + if (!deepMatches(a[prop], b[prop])) { + return false; + } + } + return true; + } else { + return false; + } + } + function removeFixtureAndXHR(query) { + if (query.fixture || query.xhr || query.data) { + var clone = canReflect.serialize(query); + delete clone.fixture; + delete clone.xhr; + delete clone.data; + return clone; + } else { + return query; + } + } + function identityIntersection(v1, v2) { + return v1.value === v2.value ? v1 : set.EMPTY; + } + function identityDifference(v1, v2) { + return v1.value === v2.value ? set.EMPTY : v1; + } + function identityUnion(v1, v2) { + return v1.value === v2.value ? v1 : set.UNDEFINABLE; + } + var identityComparitor = { + intersection: identityIntersection, + difference: identityDifference, + union: identityUnion + }; + function makeComparatorType(compare) { + var Type = function () { + }; + var SetType = function (value) { + this.value = value; + }; + SetType.prototype.isMember = function (value, root, keys) { + return compare(this.value, value, root, keys); + }; + canReflect.assignSymbols(Type, { 'can.SetType': SetType }); + set.defineComparison(SetType, SetType, identityComparitor); + set.defineComparison(set.UNIVERSAL, SetType, { + difference: function () { + return set.UNDEFINABLE; + } + }); + return Type; + } + function quickEqual(queryA, queryB) { + var dataA = queryA.data, dataB = queryB.data; + if (dataA && dataB) { + if (!deepMatches(dataA, dataB)) { + return false; + } + } + var q1 = new QueryLogic.KeysAnd(removeFixtureAndXHR(queryA)), q2 = new QueryLogic.KeysAnd(removeFixtureAndXHR(queryB)); + return set.isEqual(q1, q2); + } + function quickSubset(queryA, queryB) { + return set.isSubset(new QueryLogic.KeysAnd(queryA), new QueryLogic.KeysAnd(queryB)); + } + var types = {}; + canReflect.eachKey({ + IsEmptyOrNull: function (a, b) { + if (a == null && canReflect.size(b) === 0) { + return true; + } else if (b == null && canReflect.size(a) === 0) { + return true; + } else { + return quickEqual(a, b); + } + }, + isEmptyOrSubset: function (a, b) { + if (a == null && canReflect.size(b) === 0) { + return true; + } else if (b == null && canReflect.size(a) === 0) { + return true; + } else { + return quickSubset(a, b); + } + }, + TemplateUrl: function (a, b) { + return !!dataFromUrl(a, b); + }, + StringIgnoreCase: function (a, b) { + return b && a ? a.toLowerCase() === b.toLowerCase() : b === a; + }, + Ignore: function () { + return true; + } + }, function (compare, name) { + types[name] = makeComparatorType(compare); + }); + var schema = { + identity: ['id'], + keys: { + url: types.TemplateUrl, + fixture: types.Ignore, + xhr: types.Ignore, + type: types.StringIgnoreCase, + method: types.StringIgnoreCase, + helpers: types.Ignore, + headers: types.IsEmptyOrNull, + data: types.IsEmptyOrSubset + } + }; + var query = new QueryLogic(schema); + module.exports = { + fixture: quickEqual, + request: function (requestData, fixtureData) { + return query.isMember({ filter: fixtureData }, requestData); + }, + matches: function (settings, fixture, exact) { + if (exact) { + return this.fixture(settings, fixture); + } else { + return this.request(settings, fixture); + } + }, + makeComparatorType: makeComparatorType + }; +}); +/*can-fixture@3.0.4#test/matches-test*/ +define('can-fixture@3.0.4#test/matches-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + '../matches' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var matches = require('../matches'); + QUnit.test('core.defaultCompare', function () { + var same = matches.request({ url: '/thingers/5' }, { url: '/thingers/{id}' }); + ok(same, 'they are similar'); + same = matches.request({ url: '/thingers/5' }, { url: '/thingers' }); + ok(!same, 'they are not the same'); + }); + QUnit.test('core.matches', function () { + var same = matches.matches({ url: '/thingers/5' }, { url: '/thingers/{id}' }); + ok(same, 'similar'); + same = matches.matches({ + url: '/thingers/5', + type: 'get' + }, { url: '/thingers/{id}' }); + ok(same, 'similar with extra pops on settings'); + var exact = matches.matches({ + url: '/thingers/5', + type: 'get' + }, { url: '/thingers/{id}' }, true); + ok(!exact, 'not exact'); + exact = matches.matches({ url: '/thingers/5' }, { url: '/thingers/5' }, true); + ok(exact, 'exact'); + }); +}); +/*can-memory-store@1.0.1#make-simple-store*/ +define('can-memory-store@1.0.1#make-simple-store', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + var canReflect = require('can-reflect'); + function getItems(data) { + if (Array.isArray(data)) { + return data; + } else { + return data.data; + } + } + function indexOf(records, identity, queryLogic) { + var schema = canReflect.getSchema(queryLogic); + for (var i = 0; i < records.length; i++) { + if (identity === canReflect.getIdentity(records[i], schema)) { + return i; + } + } + return -1; + } + function makeSimpleStore(baseConnection) { + baseConnection.constructor = makeSimpleStore; + var behavior = Object.create(baseConnection); + return canReflect.assignMap(behavior, { + getRecordFromParams: function (record) { + var id = canReflect.getIdentity(record, this.queryLogic.schema); + return this.getRecord(id); + }, + log: function () { + this._log = true; + }, + getSets: function () { + return this.getQueries(); + }, + getQueries: function () { + return Promise.resolve(this.getQueriesSync()); + }, + getQueriesSync: function () { + return this.getQueryDataSync().map(function (queryData) { + return queryData.query; + }); + }, + getListData: function (query) { + query = query || {}; + var listData = this.getListDataSync(query); + if (listData) { + return Promise.resolve(listData); + } + return Promise.reject({ + title: 'no data', + status: '404', + detail: 'No data available for this query.\nAvailable queries: ' + JSON.stringify(this.getQueriesSync()) + }); + }, + getPaginatedListDataSync: function (superSetQueryData) { + var records = this.getAllRecords(); + var queryWithoutPagination = this.queryLogic.removePagination(superSetQueryData.query); + var matchingSuperRecordsNoPagination = this.queryLogic.filterMembersAndGetCount(queryWithoutPagination, {}, records); + var startIndex = indexOf(matchingSuperRecordsNoPagination.data, superSetQueryData.startIdentity, this.queryLogic); + var matchingSuperRecords = matchingSuperRecordsNoPagination.data.slice(startIndex, startIndex + this.queryLogic.count(superSetQueryData.query)); + return { + count: matchingSuperRecordsNoPagination.data.length, + data: matchingSuperRecords + }; + }, + getListDataSync: function (query) { + var queryData = this.getQueryDataSync(), superSetQueryData, isPaginated = this.queryLogic.isPaginated(query); + for (var i = 0; i < queryData.length; i++) { + var checkSet = queryData[i].query; + if (this.queryLogic.isSubset(query, checkSet)) { + superSetQueryData = queryData[i]; + } + } + var records = this.getAllRecords(); + if (isPaginated && this.queryLogic.isPaginated(superSetQueryData.query)) { + var result = this.getPaginatedListDataSync(superSetQueryData); + return this.queryLogic.filterMembersAndGetCount(query, superSetQueryData.query, result.data); + } + var matching = this.queryLogic.filterMembersAndGetCount(query, {}, records); + if (matching && matching.count) { + return matching; + } + if (superSetQueryData) { + return { + count: 0, + data: [] + }; + } + }, + updateListData: function (data, query) { + var queryData = this.getQueryDataSync(); + query = query || {}; + var clonedData = canReflect.serialize(data); + var records = getItems(clonedData); + this.updateRecordsSync(records); + var isPaginated = this.queryLogic.isPaginated(query); + var identity = records.length ? canReflect.getIdentity(records[0], this.queryLogic.schema) : undefined; + if (isPaginated) { + for (var i = 0; i < queryData.length; i++) { + var checkSet = queryData[i].query; + var union = this.queryLogic.union(checkSet, query); + if (this.queryLogic.isDefinedAndHasMembers(union)) { + var siblingRecords = this.getPaginatedListDataSync(queryData[i]); + var res = this.queryLogic.unionMembers(checkSet, query, siblingRecords.data, records); + identity = canReflect.getIdentity(res[0], this.queryLogic.schema); + queryData[i] = { + query: union, + startIdentity: identity + }; + this.updateQueryDataSync(queryData); + return Promise.resolve(); + } + } + queryData.push({ + query: query, + startIdentity: identity + }); + this.updateQueryDataSync(queryData); + return Promise.resolve(); + } + var allRecords = this.getAllRecords(); + var curretMatching = this.queryLogic.filterMembers(query, allRecords); + if (curretMatching.length) { + var toBeDeleted = new Map(); + curretMatching.forEach(function (record) { + toBeDeleted.set(canReflect.getIdentity(record, this.queryLogic.schema), record); + }, this); + records.forEach(function (record) { + toBeDeleted.delete(canReflect.getIdentity(record, this.queryLogic.schema)); + }, this); + this.destroyRecords(canReflect.toArray(toBeDeleted)); + } + var allQueries = this.getQueryDataSync(); + var notSubsets = allQueries.filter(function (existingQueryData) { + return !this.queryLogic.isSubset(existingQueryData.query, query); + }, this), superSets = notSubsets.filter(function (existingQueryData) { + return this.queryLogic.isSubset(query, existingQueryData.query); + }, this); + if (superSets.length) { + this.updateQueryDataSync(notSubsets); + } else { + this.updateQueryDataSync(notSubsets.concat([{ + query: query, + startIdentity: identity + }])); + } + return Promise.resolve(); + }, + getData: function (params) { + var id = canReflect.getIdentity(params, canReflect.getSchema(this.queryLogic)); + var res = this.getRecord(id); + if (res) { + return Promise.resolve(res); + } else { + return Promise.reject({ + title: 'no data', + status: '404', + detail: 'No record with matching identity (' + id + ').' + }); + } + }, + createData: function (record) { + this.updateRecordsSync([record]); + return Promise.resolve(canReflect.assignMap({}, this.getRecordFromParams(record))); + }, + updateData: function (record) { + if (this.errorOnMissingRecord && !this.getRecordFromParams(record)) { + var id = canReflect.getIdentity(record, this.queryLogic.schema); + return Promise.reject({ + title: 'no data', + status: '404', + detail: 'No record with matching identity (' + id + ').' + }); + } + this.updateRecordsSync([record]); + return Promise.resolve(canReflect.assignMap({}, this.getRecordFromParams(record))); + }, + destroyData: function (record) { + var id = canReflect.getIdentity(record, this.queryLogic.schema), savedRecord = this.getRecordFromParams(record); + if (this.errorOnMissingRecord && !savedRecord) { + return Promise.reject({ + title: 'no data', + status: '404', + detail: 'No record with matching identity (' + id + ').' + }); + } + this.destroyRecords([record]); + return Promise.resolve(canReflect.assignMap({}, savedRecord || record)); + } + }); + } + module.exports = makeSimpleStore; +}); +/*can-memory-store@1.0.1#can-memory-store*/ +define('can-memory-store@1.0.1#can-memory-store', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-namespace', + './make-simple-store' +], function (require, exports, module) { + var canReflect = require('can-reflect'); + var namespace = require('can-namespace'); + var makeSimpleStore = require('./make-simple-store'); + module.exports = namespace.memoryStore = function memoryStore(baseConnection) { + baseConnection.constructor = memoryStore; + var behavior = Object.create(makeSimpleStore(baseConnection)); + canReflect.assignMap(behavior, { + clear: function () { + this._instances = {}; + this._queries = []; + }, + _queryData: [], + updateQueryDataSync: function (queries) { + this._queryData = queries; + }, + getQueryDataSync: function () { + return this._queryData; + }, + _instances: {}, + getRecord: function (id) { + return this._instances[id]; + }, + getAllRecords: function () { + var records = []; + for (var id in this._instances) { + records.push(this._instances[id]); + } + return records; + }, + destroyRecords: function (records) { + canReflect.eachIndex(records, function (record) { + var id = canReflect.getIdentity(record, this.queryLogic.schema); + delete this._instances[id]; + }, this); + }, + updateRecordsSync: function (records) { + records.forEach(function (record) { + var id = canReflect.getIdentity(record, this.queryLogic.schema); + this._instances[id] = record; + }, this); + } + }); + return behavior; + }; +}); +/*can-fixture@3.0.4#store*/ +define('can-fixture@3.0.4#store', [ + 'require', + 'exports', + 'module', + 'can-query-logic', + 'can-reflect', + 'can-memory-store' +], function (require, exports, module) { + var QueryLogic = require('can-query-logic'); + var canReflect = require('can-reflect'); + var memoryStore = require('can-memory-store'); + var connectToConnection = function (method, convert) { + return function (req, res) { + this.connection[method](convert.call(this, req.data)).then(function (data) { + res(data); + }, function (err) { + res(parseInt(err.status, 10), err); + }); + }; + }; + var makeMakeItems = function (baseItems, idProp) { + return function () { + var items = [], maxId = 0; + baseItems.forEach(function (item) { + items.push(canReflect.serialize(item)); + maxId = Math.max(item[idProp], maxId); + }); + return { + maxId: maxId, + items: items + }; + }; + }; + var stringToAny = function (str) { + switch (str) { + case 'NaN': + case 'Infinity': + return +str; + case 'null': + return null; + case 'undefined': + return undefined; + case 'true': + case 'false': + return str === 'true'; + default: + var val = +str; + if (!isNaN(val)) { + return val; + } else { + return str; + } + } + }; + var Store = function (connection, makeItems, idProp) { + var schema = connection.queryLogic.schema; + var identityKey = schema.identity[0], keys = schema.keys; + if (!keys || !keys[identityKey]) { + console.warn('No type specified for identity key. Going to convert strings to reasonable type.'); + } + this.connection = connection; + this.makeItems = makeItems; + this.idProp = idProp; + this.reset(); + for (var method in Store.prototype) { + this[method] = this[method].bind(this); + } + }; + var doNotConvert = function (v) { + return v; + }; + function typeConvert(data) { + var schema = this.connection.queryLogic.schema; + var identityKey = schema.identity[0], keys = schema.keys; + if (!keys || !keys[identityKey]) { + keys = {}; + keys[identityKey] = function (value) { + return typeof value === 'string' ? stringToAny(value) : value; + }; + } + var copy = {}; + canReflect.eachKey(data, function (value, key) { + if (keys[key]) { + copy[key] = canReflect.convert(value, keys[key]); + } else { + copy[key] = value; + } + }); + return copy; + } + canReflect.assignMap(Store.prototype, { + getListData: connectToConnection('getListData', doNotConvert), + getData: connectToConnection('getData', typeConvert), + createData: function (req, res) { + var idProp = this.idProp; + req.data[idProp] = ++this.maxId; + this.connection.createData(typeConvert.call(this, req.data)).then(function (data) { + res(data); + }, function (err) { + res(403, err); + }); + }, + createInstance: function (record) { + var idProp = this.idProp; + if (!(idProp in record)) { + record[idProp] = ++this.maxId; + } + return this.connection.createData(record); + }, + updateData: connectToConnection('updateData', typeConvert), + updateInstance: function (record) { + return this.connection.updateData(record); + }, + destroyInstance: function (record) { + return this.connection.destroyData(record); + }, + destroyData: connectToConnection('destroyData', typeConvert), + reset: function (newItems) { + if (newItems) { + this.makeItems = makeMakeItems(newItems, this.idProp); + } + var itemData = this.makeItems(); + this.maxId = itemData.maxId; + this.connection.updateListData(itemData.items, {}); + }, + get: function (params) { + var id = this.connection.queryLogic.memberIdentity(params); + return this.connection.getRecord(id); + }, + getList: function (set) { + return this.connection.getListDataSync(set); + } + }); + function looksLikeAQueryLogic(obj) { + return obj && 'identityKeys' in obj; + } + Store.make = function (count, make, queryLogic) { + var makeItems, idProp; + if (typeof count === 'number') { + if (!queryLogic) { + queryLogic = new QueryLogic({}); + } else if (!looksLikeAQueryLogic(queryLogic)) { + queryLogic = new QueryLogic(queryLogic); + } + idProp = queryLogic.identityKeys()[0] || 'id'; + makeItems = function () { + var items = []; + var maxId = 0; + for (var i = 0; i < count; i++) { + var item = make(i, items); + if (!item[idProp]) { + item[idProp] = i; + } + maxId = Math.max(item[idProp], maxId); + items.push(item); + } + return { + maxId: maxId, + items: items + }; + }; + } else if (Array.isArray(count)) { + queryLogic = make; + if (!queryLogic) { + queryLogic = new QueryLogic({}); + } else if (!looksLikeAQueryLogic(queryLogic)) { + queryLogic = new QueryLogic(queryLogic); + } + idProp = queryLogic.identityKeys()[0] || 'id'; + makeItems = makeMakeItems(count, idProp); + } + var connection = memoryStore({ + queryLogic: queryLogic, + errorOnMissingRecord: true + }); + return new Store(connection, makeItems, idProp); + }; + module.exports = Store; +}); +/*can-fixture@3.0.4#core*/ +define('can-fixture@3.0.4#core', [ + 'require', + 'exports', + 'module', + 'can-key/sub/sub', + 'can-reflect', + './matches', + 'can-log', + 'can-log/dev/dev', + './data-from-url', + './store' +], function (require, exports, module) { + 'use strict'; + var sub = require('can-key/sub/sub'); + var canReflect = require('can-reflect'); + var matches = require('./matches'); + var canLog = require('can-log'); + var canDev = require('can-log/dev/dev'); + var dataFromUrl = require('./data-from-url'); + require('./store'); + var fixtures = []; + exports.fixtures = fixtures; + function isStoreLike(fixture) { + return fixture && (fixture.getData || fixture.getListData); + } + var methodMapping = { + item: { + 'GET': 'getData', + 'PUT': 'updateData', + 'DELETE': 'destroyData' + }, + list: { + 'GET': 'getListData', + 'POST': 'createData' + } + }; + function getMethodAndPath(route) { + var matches = route.match(/(GET|POST|PUT|DELETE|PATCH) (.+)/i); + if (!matches) { + return [ + undefined, + route + ]; + } + var method = matches[1]; + var path = matches[2]; + return [ + method, + path + ]; + } + function inferIdProp(url) { + var wrappedInBraces = /\{(.*)\}/; + var matches = url.match(wrappedInBraces); + var isUniqueMatch = matches && matches.length === 2; + if (isUniqueMatch) { + return matches[1]; + } + } + function getItemAndListUrls(url, idProp) { + idProp = idProp || inferIdProp(url); + if (!idProp) { + return [ + undefined, + url + ]; + } + var itemRegex = new RegExp('\\/\\{' + idProp + '\\}.*'); + var rootIsItemUrl = itemRegex.test(url); + var listUrl = rootIsItemUrl ? url.replace(itemRegex, '') : url; + var itemUrl = rootIsItemUrl ? url : url.trim() + '/{' + idProp + '}'; + return [ + itemUrl, + listUrl + ]; + } + function addStoreFixture(root, store) { + var settings = {}; + var typeAndUrl = getMethodAndPath(root); + var type = typeAndUrl[0]; + var url = typeAndUrl[1]; + var itemAndListUrls = getItemAndListUrls(url, store.idProp); + var itemUrl = itemAndListUrls[0]; + var listUrl = itemAndListUrls[1]; + if (type) { + var warning = ['fixture("' + root + '", fixture) must use a store method, not a store directly.']; + if (itemUrl) { + var itemAction = methodMapping.item[type]; + if (itemAction) { + settings[type + ' ' + itemUrl] = store[itemAction]; + var itemWarning = 'Replace with fixture("' + type + ' ' + itemUrl + '", fixture.' + itemAction + ') for items.'; + warning.push(itemWarning); + } + } + var listAction = methodMapping.list[type]; + if (listAction) { + settings[type + ' ' + listUrl] = store[listAction]; + var listWarning = 'Replace with fixture("' + type + ' ' + listUrl + '", fixture.' + listAction + ') for lists.'; + warning.push(listWarning); + } + var message = warning.join(' '); + canDev.warn(message); + } else { + var itemMapping = methodMapping.item; + for (var itemMethod in itemMapping) { + var storeItemMethod = itemMapping[itemMethod]; + settings[itemMethod + ' ' + itemUrl] = store[storeItemMethod]; + } + var listMapping = methodMapping.list; + for (var listMethod in listMapping) { + var storeListMethod = listMapping[listMethod]; + settings[listMethod + ' ' + listUrl] = store[storeListMethod]; + } + } + return settings; + } + function getSettingsFromString(route) { + var typeAndUrl = getMethodAndPath(route); + var type = typeAndUrl[0]; + var url = typeAndUrl[1]; + if (type) { + return { + type: type, + url: url + }; + } + return { url: url }; + } + function upsertFixture(fixtureList, settings, fixture) { + var index = exports.index(settings, true); + if (index > -1) { + fixtures.splice(index, 1); + } + if (fixture == null) { + return; + } + if (typeof fixture === 'object') { + var data = fixture; + fixture = function () { + return data; + }; + } + settings.fixture = fixture; + fixtures.unshift(settings); + } + exports.add = function (settings, fixture) { + if (fixture === undefined) { + canReflect.eachKey(settings, function (fixture, url) { + exports.add(url, fixture); + }); + return; + } + if (isStoreLike(fixture)) { + settings = addStoreFixture(settings, fixture); + exports.add(settings); + return; + } + if (typeof settings === 'string') { + settings = getSettingsFromString(settings); + } + upsertFixture(fixtures, settings, fixture); + }; + var $fixture = exports.add; + $fixture.on = true; + $fixture.delay = 10; + function FixtureResponse(fixture, response) { + this.statusCode = response[0]; + this.responseBody = response[1]; + this.headers = response[2]; + this.statusText = response[3]; + this.fixture = fixture; + } + exports.callDynamicFixture = function (xhrSettings, fixtureSettings, cb) { + xhrSettings.data = fixtureSettings.data; + var response = function () { + var res = exports.extractResponse.apply(xhrSettings, arguments); + return cb.apply(this, res); + }; + var callFixture = function () { + var result = fixtureSettings.fixture(xhrSettings, response, xhrSettings.headers, fixtureSettings); + if (result !== undefined) { + response(200, result); + } + }; + if (!xhrSettings.async) { + callFixture(); + return null; + } else { + return setTimeout(callFixture, $fixture.delay); + } + }; + exports.index = function (settings, exact) { + for (var i = 0; i < fixtures.length; i++) { + if (matches.matches(settings, fixtures[i], exact)) { + return i; + } + } + return -1; + }; + exports.get = function (xhrSettings) { + if (!$fixture.on) { + return; + } + var index = exports.index(xhrSettings, true); + if (index === -1) { + index = exports.index(xhrSettings, false); + } + var fixtureSettings = index >= 0 ? canReflect.assignMap({}, fixtures[index]) : undefined; + if (fixtureSettings) { + var url = fixtureSettings.fixture, data = dataFromUrl(fixtureSettings.url, xhrSettings.url); + if (typeof fixtureSettings.fixture === 'string') { + if (data) { + url = sub(url, data); + } + fixtureSettings.url = url; + fixtureSettings.data = null; + fixtureSettings.type = 'GET'; + if (!fixtureSettings.error) { + fixtureSettings.error = function (xhr, error, message) { + throw 'fixtures.js Error ' + error + ' ' + message; + }; + } + } else if (canReflect.isPlainObject(xhrSettings.data) || xhrSettings.data == null) { + var xhrData = canReflect.assignMap({}, xhrSettings.data || {}); + fixtureSettings.data = canReflect.assignMap(xhrData, data); + } else { + fixtureSettings.data = xhrSettings.data; + } + } + return fixtureSettings; + }; + exports.matches = matches; + exports.extractResponse = function (status, response, headers, statusText) { + if (typeof status !== 'number') { + headers = response; + response = status; + status = 200; + } + if (typeof headers === 'string') { + statusText = headers; + headers = {}; + } + return [ + status, + response, + headers, + statusText + ]; + }; +}); +/*can-fixture@3.0.4#xhr*/ +define('can-fixture@3.0.4#xhr', [ + 'require', + 'exports', + 'module', + './core', + 'can-deparam', + 'can-reflect', + 'can-log' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var fixtureCore = require('./core'); + var deparam = require('can-deparam'); + var canReflect = require('can-reflect'); + var canLog = require('can-log'); + var XHR = XMLHttpRequest, GLOBAL = typeof global !== 'undefined' ? global : window; + var props = [ + 'type', + 'url', + 'async', + 'response', + 'responseText', + 'responseType', + 'responseXML', + 'responseURL', + 'status', + 'statusText', + 'readyState' + ]; + var events = [ + 'abort', + 'error', + 'load', + 'loadend', + 'loadstart', + 'progress', + 'readystatechange' + ]; + (function () { + var x = new XHR(); + for (var prop in x) { + if (prop.indexOf('on') === 0) { + if (events.indexOf(prop.substr(2)) === -1) { + events.push(prop.substr(2)); + } + } else if (props.indexOf(prop) === -1 && typeof x[prop] !== 'function') { + props.push(prop); + } + } + }()); + function callEvents(xhr, ev) { + var evs = xhr.__events[ev] || [], fn; + for (var i = 0, len = evs.length; i < len; i++) { + fn = evs[i]; + fn.call(xhr); + } + } + function defineNonEnumerable(obj, prop, value) { + Object.defineProperty(obj, prop, { + enumerable: false, + configurable: true, + writable: true, + value: value + }); + } + GLOBAL.XMLHttpRequest = function () { + var mockXHR = this; + var realXHR = new XHR(); + defineNonEnumerable(this, '_xhr', realXHR); + defineNonEnumerable(this, '_requestHeaders', {}); + defineNonEnumerable(this, '__events', {}); + events.forEach(function (eventName) { + realXHR['on' + eventName] = function () { + callEvents(mockXHR, eventName); + if (mockXHR['on' + eventName]) { + return mockXHR['on' + eventName].apply(mockXHR, arguments); + } + }; + }); + this.onload = null; + }; + GLOBAL.XMLHttpRequest._XHR = XHR; + canReflect.assignMap(XMLHttpRequest.prototype, { + setRequestHeader: function (name, value) { + this._requestHeaders[name] = value; + }, + open: function (type, url, async) { + this.type = type; + this.url = url; + this.async = async === false ? false : true; + }, + getAllResponseHeaders: function () { + return this._xhr.getAllResponseHeaders.apply(this._xhr, arguments); + }, + addEventListener: function (ev, fn) { + var evs = this.__events[ev] = this.__events[ev] || []; + evs.push(fn); + }, + removeEventListener: function (ev, fn) { + var evs = this.__events[ev] = this.__events[ev] || []; + var idx = evs.indexOf(fn); + if (idx >= 0) { + evs.splice(idx, 1); + } + }, + setDisableHeaderCheck: function (val) { + this._disableHeaderCheck = !!val; + }, + getResponseHeader: function (key) { + return this._xhr.getResponseHeader(key); + }, + abort: function () { + var xhr = this._xhr; + if (this.timeoutId !== undefined) { + clearTimeout(this.timeoutId); + xhr.open(this.type, this.url, this.async === false ? false : true); + xhr.send(); + } + return xhr.abort(); + }, + send: function (data) { + var type = this.type.toLowerCase() || 'get'; + var xhrSettings = { + url: this.url, + data: data, + headers: this._requestHeaders, + type: type, + method: type, + async: this.async, + xhr: this + }; + if (!xhrSettings.data && xhrSettings.type === 'get' || xhrSettings.type === 'delete') { + xhrSettings.data = deparam(xhrSettings.url.split('?')[1]); + xhrSettings.url = xhrSettings.url.split('?')[0]; + } + if (typeof xhrSettings.data === 'string') { + try { + xhrSettings.data = JSON.parse(xhrSettings.data); + } catch (e) { + xhrSettings.data = deparam(xhrSettings.data); + } + } + var fixtureSettings = fixtureCore.get(xhrSettings); + var mockXHR = this; + if (fixtureSettings && typeof fixtureSettings.fixture === 'function') { + this.timeoutId = fixtureCore.callDynamicFixture(xhrSettings, fixtureSettings, function (status, body, headers, statusText) { + body = typeof body === 'string' ? body : JSON.stringify(body); + mockXHR._xhr = { + open: function () { + }, + send: function () { + }, + abort: function () { + }, + getResponseHeader: function () { + } + }; + canReflect.assignMap(mockXHR, { + readyState: 4, + status: status + }); + var success = status >= 200 && status < 300 || status === 304; + if (success) { + canReflect.assignMap(mockXHR, { + statusText: statusText || 'OK', + responseText: body + }); + } else { + canReflect.assignMap(mockXHR, { + statusText: statusText || 'error', + responseText: body + }); + } + mockXHR.getAllResponseHeaders = function () { + var ret = []; + canReflect.eachKey(headers || {}, function (value, name) { + Array.prototype.push.apply(ret, [ + name, + ': ', + value, + '\r\n' + ]); + }); + return ret.join(''); + }; + if (mockXHR.onreadystatechange) { + mockXHR.onreadystatechange({ target: mockXHR }); + } + callEvents(mockXHR, 'progress'); + if (mockXHR.onprogress) { + mockXHR.onprogress(); + } + callEvents(mockXHR, 'load'); + if (mockXHR.onload) { + mockXHR.onload(); + } + callEvents(mockXHR, 'loadend'); + if (mockXHR.onloadend) { + mockXHR.onloadend(); + } + }); + return; + } + var makeRequest = function () { + mockXHR._xhr.open(mockXHR._xhr.type, mockXHR._xhr.url, mockXHR._xhr.async); + if (mockXHR._requestHeaders) { + Object.keys(mockXHR._requestHeaders).forEach(function (key) { + mockXHR._xhr.setRequestHeader(key, mockXHR._requestHeaders[key]); + }); + } + return mockXHR._xhr.send(data); + }; + if (fixtureSettings && typeof fixtureSettings.fixture === 'number') { + canLog.log('can-fixture: ' + xhrSettings.url + ' => delay ' + fixtureSettings.fixture + 'ms'); + this.timeoutId = setTimeout(makeRequest, fixtureSettings.fixture); + return; + } + if (fixtureSettings) { + canLog.log('can-fixture: ' + xhrSettings.url + ' => ' + fixtureSettings.url); + canReflect.assignMap(mockXHR, fixtureSettings); + } + return makeRequest(); + } + }); + props.forEach(function (prop) { + Object.defineProperty(XMLHttpRequest.prototype, prop, { + get: function () { + return this._xhr[prop]; + }, + set: function (newVal) { + try { + this._xhr[prop] = newVal; + } catch (e) { + } + } + }); + }); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-fixture@3.0.4#fixture*/ +define('can-fixture@3.0.4#fixture', [ + 'require', + 'exports', + 'module', + './core', + './store', + './xhr', + 'can-reflect', + 'can-namespace' +], function (require, exports, module) { + 'use strict'; + var core = require('./core'); + var fixture = core.add; + var Store = require('./store'); + require('./xhr'); + var canReflect = require('can-reflect'); + var ns = require('can-namespace'); + var noop = function () { + }; + canReflect.assignMap(fixture, { + rand: function randomize(arr, min, max) { + if (typeof arr === 'number') { + if (typeof min === 'number') { + return arr + Math.floor(Math.random() * (min - arr + 1)); + } else { + return Math.floor(Math.random() * (arr + 1)); + } + } + var choices = arr.slice(0); + if (min === undefined) { + min = 1; + max = choices.length; + } else if (max === undefined) { + max = min; + } + var result = []; + var selectedCount = min + Math.round(randomize(max - min)); + for (var i = 0; i < selectedCount; i++) { + var selectedIndex = randomize(choices.length - 1), selected = choices.splice(selectedIndex, 1)[0]; + result.push(selected); + } + return result; + }, + xhr: function (xhr) { + return canReflect.assignMap({}, { + abort: noop, + getAllResponseHeaders: function () { + return ''; + }, + getResponseHeader: function () { + return ''; + }, + open: noop, + overrideMimeType: noop, + readyState: 4, + responseText: '', + responseXML: null, + send: noop, + setRequestHeader: noop, + status: 200, + statusText: 'OK' + }, xhr); + }, + store: Store.make, + fixtures: core.fixtures + }); + if (typeof window !== 'undefined' && typeof require.resolve !== 'function') { + window.fixture = fixture; + } + module.exports = ns.fixture = fixture; +}); +/*can-fixture@3.0.4#test/store-test*/ +define('can-fixture@3.0.4#test/store-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-fixture', + 'can-query-logic', + 'can-reflect' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var fixture = require('can-fixture'); + var QueryLogic = require('can-query-logic'); + var canReflect = require('can-reflect'); + QUnit.module('can-fixture.store'); + QUnit.test('createInstance, destroyInstance, updateInstance', function (assert) { + var store = fixture.store([{ + id: 0, + name: 'foo' + }], new QueryLogic({ identity: ['id'] })); + QUnit.stop(); + store.createInstance({ name: 'bar' }).then(function (instance) { + var data = store.getList({}); + assert.deepEqual(data, { + count: 2, + data: [ + { + id: 0, + name: 'foo' + }, + { + id: 1, + name: 'bar' + } + ] + }); + return store.updateInstance({ + id: 1, + name: 'updated' + }); + }).then(function (instance) { + var data = store.getList({}); + assert.deepEqual(data, { + count: 2, + data: [ + { + id: 0, + name: 'foo' + }, + { + id: 1, + name: 'updated' + } + ] + }); + return store.destroyInstance(instance); + }).then(function () { + var data = store.getList({}); + assert.deepEqual(data, { + count: 1, + data: [{ + id: 0, + name: 'foo' + }] + }); + QUnit.start(); + }); + }); + QUnit.test('anything with a schema will be converted to a queryLogic automatically', function () { + var store = fixture.store([{ + _id: 0, + name: 'foo' + }], { identity: ['id'] }); + var res = store.get({ _id: 0 }); + QUnit.ok(res, 'an object works'); + var type = canReflect.assignSymbols({}, { + 'can.getSchema': function () { + return { identity: ['id'] }; + } + }); + store = fixture.store([{ + _id: 0, + name: 'foo' + }], type); + res = store.get({ _id: 0 }); + QUnit.ok(res, 'an object works'); + }); + QUnit.test('createData, destroyData, updateData', function (assert) { + var store = fixture.store([{ + id: 0, + name: 'foo' + }], new QueryLogic({ identity: ['id'] })); + QUnit.stop(); + store.createData({ data: { name: 'bar' } }, function (instance) { + QUnit.deepEqual(instance, { + id: 1, + name: 'bar' + }); + QUnit.start(); + }); + }); +}); +/*can-set-legacy@1.0.0#can-set-legacy*/ +define('can-set-legacy@1.0.0#can-set-legacy', [ + 'require', + 'exports', + 'module', + 'can-query-logic', + 'can-reflect', + 'can-key/transform/transform', + 'can-key/delete/delete', + 'can-key/get/get', + 'can-query-logic/src/helpers', + 'can-query-logic/src/types/make-enum', + 'can-query-logic/src/set' +], function (require, exports, module) { + var Query = require('can-query-logic'); + var canReflect = require('can-reflect'); + var transform = require('can-key/transform/transform'); + var deleteKey = require('can-key/delete/delete'); + var getKey = require('can-key/get/get'); + var helpers = require('can-query-logic/src/helpers'); + var makeEnum = require('can-query-logic/src/types/make-enum'); + var SET = require('can-query-logic/src/set'); + var IsBoolean = function () { + }; + makeEnum(IsBoolean, [ + true, + false + ], function (value) { + if (value === 'true') { + return true; + } else if (value === 'false') { + return false; + } else { + return value; + } + }); + function hasKey(obj, keys, parent, parentKey) { + if (obj && typeof obj === 'object') { + for (var key in obj) { + if (keys[key]) { + if (typeof keys[key] === 'function') { + parent[parentKey] = keys[key](obj); + } else { + return true; + } + } else { + if (hasKey(obj[key], keys, obj, key)) { + return true; + } + } + } + } + return false; + } + function convertToJSONAPISort(sortPropValue) { + var parts = sortPropValue.split(' '); + var isDesc = (parts[1] || '').toLowerCase() === 'desc'; + return isDesc ? '-' + parts[0] : parts[0]; + } + function convertToLegacySort(value) { + var result = helpers.sortData(value); + return result.desc ? '-' + result.prop : result.prop; + } + var defaultAlgebra; + var set = { + UNIVERSAL: SET.UNIVERSAL, + EMPTY: SET.EMPTY, + UNDEFINABLE: SET.UNDEFINABLE, + UNKNOWABLE: SET.UNKNOWABLE, + Algebra: function () { + var mutators = { + schema: [], + hydrate: [], + serialize: [] + }; + canReflect.eachIndex(arguments, function (value) { + for (var prop in value) { + if (mutators[prop]) { + mutators[prop].push(value[prop]); + } else { + throw new Error('can-query-logic: This type of configuration is not supported. Please use can-query-logic directly.'); + } + } + }); + var obj = canReflect.assignSymbols({}, { + 'can.getSchema': function () { + var schema = { + kind: 'record', + identity: [], + keys: {} + }; + mutators.schema.forEach(function (updateSchema) { + updateSchema(schema); + }); + if (!schema.identity.length) { + schema.identity.push('id'); + } + return schema; + } + }); + return new Query(obj, { + toQuery: function (data) { + return mutators.hydrate.reduce(function (last, hydrator) { + return hydrator(last); + }, { filter: data }); + }, + toParams: function (data) { + if (SET.isSpecial(data)) { + return data; + } + if (Array.isArray(data.filter)) { + return SET.UNDEFINABLE; + } + var filter = data.filter || {}; + if (hasKey(filter, { + '$ne': true, + '$in': function (val) { + return val.$in; + } + })) { + return SET.UNDEFINABLE; + } + var out = mutators.serialize.reduce(function (last, serializer) { + return serializer(last); + }, data); + filter = out.filter || {}; + delete out.filter; + return canReflect.assign(out, filter); + } + }); + }, + Translate: function (clause, prop) { + if (clause !== 'where') { + throw new Error('can-query-logic/compat.Translate is only able to translate the where clause'); + } + return { + hydrate: function (raw) { + var clone = canReflect.serialize(raw); + var value = clone.filter[prop]; + delete clone.filter[prop]; + if (value) { + canReflect.assign(clone.filter, value); + } + return clone; + }, + serialize: function (query) { + if (query.filter) { + var clone = canReflect.serialize(query); + var filter = query.filter; + clone.filter = {}; + clone.filter[prop] = filter; + return clone; + } else { + return query; + } + } + }; + }, + props: { + boolean: function (prop) { + return { + schema: function (schema) { + schema.keys[prop] = IsBoolean; + } + }; + }, + dotNotation: function () { + return {}; + }, + enum: function (property, propertyValues) { + function Enum() { + } + makeEnum(Enum, propertyValues); + return { + schema: function (schema) { + schema.keys[property] = Enum; + } + }; + }, + id: function (id) { + return { + 'schema': function (schema) { + schema.identity.push(id); + } + }; + }, + offsetLimit: function (offset, limit) { + offset = offset || 'offset'; + limit = limit || 'limit'; + return { + hydrate: function (raw) { + var clone = canReflect.serialize(raw); + if (offset in clone.filter || limit in clone.filter) { + clone.page = {}; + } + if (offset in clone.filter) { + clone.page.start = parseInt(clone.filter[offset], 10); + delete clone.filter[offset]; + } + if (limit in clone.filter) { + clone.page.end = (clone.page.start || 0) + parseInt(clone.filter[limit], 10) - 1; + delete clone.filter[limit]; + } + return clone; + }, + serialize: function (raw) { + var clone = canReflect.serialize(raw); + if (clone.page) { + clone[offset] = clone.page.start; + clone[limit] = clone.page.end - clone.page.start + 1; + delete clone.page; + } + return clone; + } + }; + }, + rangeInclusive: function (start, end) { + var hydrateTransfomer = {}; + hydrateTransfomer['filter.' + start] = 'page.start'; + hydrateTransfomer['filter.' + end] = 'page.end'; + var serializeTransformer = { + 'page.start': start, + 'page.end': end + }; + return { + hydrate: function (raw) { + var res = transform(raw, hydrateTransfomer); + if (res.page) { + if (res.page.start) { + res.page.start = parseInt(res.page.start, 10); + } + if (res.page.end) { + res.page.end = parseInt(res.page.end, 10); + } + } + return res; + }, + serialize: function (raw) { + return transform(raw, serializeTransformer); + } + }; + }, + ignore: function (prop) { + return { + hydrate: function (raw) { + var clone = canReflect.serialize(raw); + delete clone.filter[prop]; + return clone; + } + }; + }, + sort: function (prop, sortFunc) { + if (!prop) { + prop = 'sort'; + } + if (sortFunc) { + throw new Error('can-query-logic/compat.sort - sortFunc is not supported'); + } + return { + hydrate: function (raw) { + var clone = canReflect.serialize(raw); + var sort = getKey(clone, 'filter.' + prop); + if (sort !== undefined) { + deleteKey(clone, 'filter.' + prop); + clone.sort = convertToJSONAPISort(sort); + } + return clone; + }, + serialize: function (raw) { + var clone = canReflect.serialize(raw); + var sort = clone.sort; + if (sort !== undefined) { + delete clone.sort; + clone[prop] = convertToLegacySort(sort); + } + return clone; + } + }; + } + } + }; + function makeAlgebra(algebra) { + if (!algebra) { + return defaultAlgebra; + } else if (!(algebra instanceof Query)) { + return new set.Algebra(algebra); + } + return algebra; + } + function makeFromTwoQueries(prop) { + set[prop] = function (a, b, algebra) { + return makeAlgebra(algebra)[prop](a, b); + }; + } + makeFromTwoQueries('difference'); + makeFromTwoQueries('union'); + makeFromTwoQueries('intersection'); + makeFromTwoQueries('isSubset'); + makeFromTwoQueries('isEqual'); + makeFromTwoQueries('isProperSubset'); + set.count = function (query, algebra) { + return makeAlgebra(algebra).count(query); + }; + set.comparators = set.props; + defaultAlgebra = new set.Algebra(); + module.exports = set; +}); +/*can-fixture@3.0.4#test/fixture_test*/ +define('can-fixture@3.0.4#test/fixture_test', [ + 'require', + 'exports', + 'module', + './matches-test', + './store-test', + 'steal-qunit', + 'can-fixture', + 'can-set-legacy', + 'jquery', + 'can-log/dev/dev', + '../data-from-url', + 'can-reflect', + '../matches', + 'can-query-logic', + 'can-test-helpers' +], function (require, exports, module) { + (function (__dirname, require, exports, module) { + require('./matches-test'); + require('./store-test'); + var QUnit = require('steal-qunit'); + var fixture = require('can-fixture'); + var set = require('can-set-legacy'); + var $ = require('jquery'); + var canDev = require('can-log/dev/dev'); + var dataFromUrl = require('../data-from-url'); + var canReflect = require('can-reflect'); + var matches = require('../matches'); + var QueryLogic = require('can-query-logic'); + var testHelpers = require('can-test-helpers'); + var errorCallback = function (xhr, status, error) { + ok(false, error); + start(); + }; + var parseHeaders = function (str) { + var lines = str.split(/\r?\n/); + var fields = {}; + var index; + var line; + var field; + var val; + lines.pop(); + for (var i = 0, len = lines.length; i < len; ++i) { + line = lines[i]; + index = line.indexOf(':'); + field = line.slice(0, index).toLowerCase(); + val = line.slice(index + 1).replace(/(^\s*|\s*$)/g, ''); + fields[field] = val; + } + return fields; + }; + QUnit.module('can-fixture'); + if (__dirname !== '/') { + test('static fixtures', function () { + stop(); + fixture('GET something', __dirname + '/fixtures/test.json'); + fixture('POST something', __dirname + '/fixtures/test.json'); + fixture('PATCH something', __dirname + '/fixtures/test.json'); + $.ajax({ + url: 'something', + dataType: 'json' + }).then(function (data) { + equal(data.sweet, 'ness', 'can.get works'); + $.ajax({ + url: 'something', + method: 'POST', + dataType: 'json' + }).then(function (data) { + equal(data.sweet, 'ness', 'can.post works'); + $.ajax({ + url: 'something', + method: 'PATCH', + dataType: 'json' + }).then(function (data) { + equal(data.sweet, 'ness', 'can.patch works'); + start(); + }, errorCallback); + }, errorCallback); + }, errorCallback); + }); + } + if (__dirname !== '/') { + test('static fixtures (using method signature)', function () { + stop(); + fixture({ + method: 'get', + url: 'method/{id}' + }, __dirname + '/fixtures/method.{id}.json'); + $.ajax({ + url: 'method/4', + dataType: 'json' + }).then(function (data) { + equal(data.id, 4, 'Got data with proper id using method'); + start(); + }, errorCallback); + }); + } + if (__dirname !== '/') { + test('static fixtures (using type signature)', function () { + stop(); + fixture({ + type: 'get', + url: 'type/{id}' + }, __dirname + '/fixtures/type.{id}.json'); + $.ajax({ + url: 'type/4', + dataType: 'json' + }).then(function (data) { + equal(data.id, 4, 'Got data with proper id using type'); + start(); + }, errorCallback); + }); + } + if (__dirname !== '/') { + test('templated static fixtures', function () { + stop(); + fixture('GET some/{id}', __dirname + '/fixtures/stuff.{id}.json'); + $.ajax({ + url: 'some/3', + dataType: 'json' + }).then(function (data) { + equal(data.id, 3, 'Got data with proper id'); + start(); + }, errorCallback); + }); + } + test('dynamic fixtures', function () { + stop(); + fixture.delay = 10; + fixture('something', function () { + return [{ sweet: 'ness' }]; + }); + $.ajax({ + url: 'something', + dataType: 'json' + }).done(function (data) { + equal(data[0].sweet, 'ness', 'can.get works'); + start(); + }).catch(function (err) { + debugger; + }); + }); + if (__dirname !== '/') { + test('fixture function', 3, function () { + stop(); + var url = __dirname + '/fixtures/foo.json'; + fixture(url, __dirname + '/fixtures/foobar.json'); + $.ajax({ + url: url, + dataType: 'json' + }).done(function (data) { + equal(data.sweet, 'ner', 'url passed works'); + fixture(url, __dirname + '/fixtures/test.json'); + $.ajax({ + url: url, + dataType: 'json' + }).done(function (data) { + equal(data.sweet, 'ness', 'replaced'); + fixture(url, null); + $.ajax({ + url: url, + dataType: 'json' + }).done(function (data) { + equal(data.a, 'b', 'removed'); + start(); + }); + }); + }); + }); + } + test('fixture.store fixtures', function () { + stop(); + var SearchText = matches.makeComparatorType(function (searchTextValue, dataSearchTextValue, data, path) { + var regex = new RegExp('^' + searchTextValue); + return regex.test(data.name); + }); + var algebra = new set.Algebra({ + schema: function (schema) { + schema.keys.searchText = SearchText; + } + }, set.props.offsetLimit('offset', 'limit'), set.props.sort('order')); + var store = fixture.store(1000, function (i) { + return { + id: i, + name: 'thing ' + i + }; + }, algebra); + fixture('things', store.getListData); + $.ajax({ + url: 'things', + dataType: 'json', + data: { + offset: 100, + limit: 200, + order: 'name ASC', + searchText: 'thing 2' + }, + success: function (things) { + equal(things.data[0].name, 'thing 29', 'first item is correct'); + equal(things.data.length, 11, 'there are 11 items'); + start(); + } + }); + }); + test('fixture.store fixtures should have unique IDs', function () { + stop(); + var store = fixture.store(100, function (i) { + return { name: 'Test ' + i }; + }); + fixture('things', store.getListData); + $.ajax({ + url: 'things', + dataType: 'json', + data: { + page: { + start: 0, + end: 199 + }, + order: 'name ASC' + }, + success: function (result) { + var seenIds = []; + var things = result.data; + for (var thingKey in things) { + var thing = things[thingKey]; + ok(seenIds.indexOf(thing.id) === -1); + seenIds.push(thing.id); + } + start(); + } + }); + }); + test('fixture.store should assign unique IDs when fixtures provide IDs', function () { + var store = fixture.store([ + { + id: 0, + name: 'Object 0' + }, + { + id: 1, + name: 'Object 1' + }, + { + id: 2, + name: 'Object 2' + } + ]); + fixture('POST /models', store.createData); + function then(ajax, callback) { + ajax.then(callback, function (error) { + ok(false, 'ajax failure: ' + error); + start(); + }); + } + var request = $.ajax({ + url: '/models', + dataType: 'json', + type: 'post', + data: { name: 'My test object' } + }); + stop(); + then(request, function (response) { + notEqual(response.id, 0); + notEqual(response.id, 1); + notEqual(response.id, 2); + equal(response.id, 3); + start(); + }); + }); + test('simulating an error', function () { + fixture('/foo', function (request, response) { + return response(401, { type: 'unauthorized' }); + }); + stop(); + $.ajax({ + url: '/foo', + dataType: 'json' + }).done(function () { + ok(false, 'success called'); + start(); + }).fail(function (original, type) { + ok(true, 'error called'); + deepEqual(JSON.parse(original.responseText), { type: 'unauthorized' }, 'Original text passed'); + start(); + }); + }); + test('rand', function () { + var rand = fixture.rand; + var num = rand(3); + equal(typeof num, 'number'); + var matched = {}; + for (var i = 0; i < 100; i++) { + num = rand(3); + matched[num] = true; + } + for (i = 0; i <= 3; i++) { + ok(matched[i], 'has ' + i); + } + matched = {}; + var result, choices = [ + 'a', + 'b', + 'c' + ]; + for (i = 0; i < 100; i++) { + result = rand(choices); + matched[result.length] = true; + matched[result[0]] = true; + } + for (i = 1; i <= 3; i++) { + ok(matched[i], 'has ' + i); + delete matched[i]; + } + choices.forEach(function (choice) { + ok(matched[choice], 'has ' + choice); + delete matched[choice]; + }); + ok(canReflect.size(matched) === 0, 'nothing else unexpected'); + }); + test('dataFromUrl', function () { + var data = dataFromUrl('/thingers/{id}', '/thingers/5'); + equal(data.id, 5, 'gets data'); + data = dataFromUrl('/thingers/5?hi.there', '/thingers/5?hi.there'); + deepEqual(data, {}, 'gets data'); + }); + test('core.dataFromUrl with double character value', function () { + var data = dataFromUrl('/days/{id}/time_slots.json', '/days/17/time_slots.json'); + equal(data.id, 17, 'gets data'); + }); + test('fixture function gets id', function () { + fixture('/thingers/{id}', function (settings) { + return { + id: settings.data.id, + name: 'justin' + }; + }); + stop(); + $.ajax({ + url: '/thingers/5', + dataType: 'json', + data: { id: 5 } + }).done(function (data) { + ok(data.id); + start(); + }); + }); + if (__dirname !== '/') { + test('replacing and removing a fixture', function () { + var url = __dirname + '/fixtures/remove.json'; + fixture('GET ' + url, function () { + return { weird: 'ness!' }; + }); + stop(); + $.ajax({ + url: url, + dataType: 'json' + }).done(function (json) { + equal(json.weird, 'ness!', 'fixture set right'); + fixture('GET ' + url, function () { + return { weird: 'ness?' }; + }); + $.ajax({ + url: url, + dataType: 'json' + }).done(function (json) { + equal(json.weird, 'ness?', 'fixture set right'); + fixture('GET ' + url, null); + $.ajax({ + url: url, + dataType: 'json' + }).done(function (json) { + equal(json.weird, 'ness', 'fixture set right'); + start(); + }); + }); + }); + }); + } + test('fixture.store with can.Model', function () { + var store = fixture.store(100, function (i) { + return { + id: i, + name: 'Object ' + i + }; + }); + fixture('GET /models', store.getListData); + fixture('GET /models/{id}', store.getData); + fixture('POST /models', store.createData); + fixture('PUT /models/{id}', store.updateData); + fixture('DELETE /models/{id}', store.destroyData); + stop(); + function errorAndStart(e) { + ok(false, 'borked' + e); + start(); + } + var check100Updated = function () { + return $.ajax({ + url: '/models/100', + dataType: 'json' + }).then(function (model) { + equal(model.name, 'Updated test object', 'Successfully updated object'); + }); + }; + $.ajax({ + url: '/models', + dataType: 'json' + }).then(function (modelsData) { + var models = modelsData.data; + equal(models.length, 100, 'Got 100 models for findAll with no parameters'); + equal(models[95].name, 'Object 95', 'All models generated properly'); + return $.ajax({ + url: '/models/51', + dataType: 'json' + }).then(function (data) { + equal(data.id, 51, 'Got correct object id'); + equal('Object 51', data.name, 'Object name generated correctly'); + return $.ajax({ + url: '/models', + dataType: 'json', + type: 'post', + data: { name: 'My test object' } + }).then(function (newmodel) { + equal(newmodel.id, 100, 'Id got incremented'); + return $.ajax({ + url: '/models/100', + dataType: 'json' + }).then(function (model) { + equal(model.id, 100, 'Loaded new object'); + return $.ajax({ + url: '/models/100', + dataType: 'json', + type: 'put', + data: { name: 'Updated test object' } + }).then(function (model) { + return check100Updated().then(function () { + return $.ajax({ + url: '/models/100', + dataType: 'json', + type: 'delete' + }).then(function (deleted) { + start(); + }, errorAndStart); + }, errorAndStart); + }, errorAndStart); + }, errorAndStart); + }, errorAndStart); + }, errorAndStart); + }, errorAndStart); + }); + test('GET fixture.store returns 404 on findOne with bad id (#803)', function () { + var store = fixture.store(2, function (i) { + return { + id: i, + name: 'Object ' + i + }; + }); + fixture('GET /models/{id}', store.getData); + stop(); + $.ajax({ + url: '/models/3', + dataType: 'json' + }).then(function () { + }, function (data) { + equal(data.status, 404, 'status'); + equal(data.statusText, 'error', 'statusText'); + equal(JSON.parse(data.responseText).title, 'no data', 'responseText'); + start(); + }); + }); + test('fixture.store returns 404 on update with a bad id (#803)', function () { + var store = fixture.store(5, function (i) { + return { + id: i, + name: 'Object ' + i + }; + }); + stop(); + fixture('POST /models/{id}', store.updateData); + $.ajax({ + url: '/models/6', + dataType: 'json', + data: { 'jedan': 'dva' }, + type: 'POST' + }).then(function () { + QUnit.ok(false, 'success'); + QUnit.start(); + }, function (data) { + equal(data.status, 404, 'status'); + equal(data.statusText, 'error', 'statusText'); + equal(JSON.parse(data.responseText).title, 'no data', 'responseText'); + start(); + }); + }); + test('fixture.store returns 404 on destroy with a bad id (#803)', function () { + var store = fixture.store(2, function (i) { + return { + id: i, + name: 'Object ' + i + }; + }); + stop(); + fixture('DELETE /models/{id}', store.destroyData); + $.ajax({ + url: '/models/6', + dataType: 'json', + type: 'DELETE' + }).then(function () { + }, function (data) { + equal(data.status, 404, 'status'); + equal(data.statusText, 'error', 'statusText'); + equal(JSON.parse(data.responseText).title, 'no data', 'responseText'); + start(); + }); + }); + test('fixture.store can use id of different type (#742)', function () { + var MustBeNumber = matches.makeComparatorType(function (queryVal, propVal) { + return parseInt(queryVal, 10) === propVal; + }); + var query = new QueryLogic({ keys: { parentId: MustBeNumber } }); + var store = fixture.store(100, function (i) { + return { + id: i, + parentId: i * 2, + name: 'Object ' + i + }; + }, query); + fixture('GET /models', store.getListData); + stop(); + $.ajax({ + url: '/models', + dataType: 'json', + data: { filter: { parentId: '4' } } + }).then(function (models) { + equal(models.data.length, 1, 'Got one model'); + deepEqual(models.data[0], { + id: 2, + parentId: 4, + name: 'Object 2' + }); + start(); + }); + }); + test('fixture("METHOD /path", store) should use the right method', function () { + var store = fixture.store(100, function (i) { + return { + id: i, + name: 'Object ' + i + }; + }); + fixture('GET /models', store); + stop(); + $.ajax({ + url: '/models', + dataType: 'json' + }).then(function (models) { + equal(models.data.length, 100, 'Gotta catch up all!'); + start(); + }); + }); + test('fixture with response callback', 4, function () { + fixture.delay = 10; + fixture('responseCb', function (orig, response) { + response({ sweet: 'ness' }); + }); + fixture('responseErrorCb', function (orig, response) { + response(404, 'This is an error from callback'); + }); + stop(); + $.ajax({ + url: 'responseCb', + dataType: 'json' + }).done(function (data) { + equal(data.sweet, 'ness', 'can.get works'); + start(); + }); + stop(); + $.ajax({ + url: 'responseErrorCb', + dataType: 'json' + }).fail(function (orig, error, text) { + equal(error, 'error', 'Got error status'); + equal(orig.responseText, 'This is an error from callback', 'Got error text'); + start(); + }); + stop(); + fixture('cbWithTimeout', function (orig, response) { + setTimeout(function () { + response([{ epic: 'ness' }]); + }, 10); + }); + $.ajax({ + url: 'cbWithTimeout', + dataType: 'json' + }).done(function (data) { + equal(data[0].epic, 'ness', 'Got responsen with timeout'); + start(); + }); + }); + test('store create works with an empty array of items', function () { + var store = fixture.store(0, function () { + return {}; + }); + QUnit.stop(); + store.createData({ data: {} }, function (responseData, responseHeaders) { + equal(responseData.id, 1, 'the first id is 1'); + QUnit.start(); + }); + }); + QUnit.test('store creates sequential ids', function () { + var store = fixture.store(0, function () { + return {}; + }); + QUnit.stop(); + store.createData({ data: {} }, function (responseData, responseHeaders) { + equal(responseData.id, 1, 'the first id is 1'); + createSecond(); + }); + function createSecond() { + store.createData({ data: {} }, function (responseData, responseHeaders) { + equal(responseData.id, 2, 'the second id is 2'); + destroyFirst(); + }); + } + function destroyFirst() { + store.destroyData({ data: { id: 1 } }, createThird); + } + function createThird() { + store.createData({ data: {} }, function (responseData, responseHeaders) { + equal(responseData.id, 3, 'the third id is 3'); + QUnit.start(); + }); + } + }); + test('fixture updates request.data with id', function () { + expect(1); + stop(); + fixture('foo/{id}', function (request) { + equal(request.data.id, 5); + start(); + }); + $.ajax({ url: 'foo/5' }); + }); + test('create a store with array and comparison object', function () { + var SoftEq = matches.makeComparatorType(function (a, b) { + return a == b; + }); + var query = new QueryLogic({ + keys: { + year: SoftEq, + modelId: SoftEq + } + }); + var store = fixture.store([ + { + id: 1, + modelId: 1, + year: 2013, + name: '2013 Mustang', + thumb: 'http://mustangsdaily.com/blog/wp-content/uploads/2012/07/01-2013-ford-mustang-gt-review-585x388.jpg' + }, + { + id: 2, + modelId: 1, + year: 2014, + name: '2014 Mustang', + thumb: 'http://mustangsdaily.com/blog/wp-content/uploads/2013/03/2014-roush-mustang.jpg' + }, + { + id: 2, + modelId: 2, + year: 2013, + name: '2013 Focus', + thumb: 'http://images.newcars.com/images/car-pictures/original/2013-Ford-Focus-Sedan-S-4dr-Sedan-Exterior.png' + }, + { + id: 2, + modelId: 2, + year: 2014, + name: '2014 Focus', + thumb: 'http://ipinvite.iperceptions.com/Invitations/survey705/images_V2/top4.jpg' + }, + { + id: 2, + modelId: 3, + year: 2013, + name: '2013 Altima', + thumb: 'http://www.blogcdn.com/www.autoblog.com/media/2012/04/04-2013-nissan-altima-1333416664.jpg' + }, + { + id: 2, + modelId: 3, + year: 2014, + name: '2014 Altima', + thumb: 'http://www.blogcdn.com/www.autoblog.com/media/2012/04/01-2013-nissan-altima-ny.jpg' + }, + { + id: 2, + modelId: 4, + year: 2013, + name: '2013 Leaf', + thumb: 'http://www.blogcdn.com/www.autoblog.com/media/2012/04/01-2013-nissan-altima-ny.jpg' + }, + { + id: 2, + modelId: 4, + year: 2014, + name: '2014 Leaf', + thumb: 'http://images.thecarconnection.com/med/2013-nissan-leaf_100414473_m.jpg' + } + ], query); + fixture('GET /presetStore', store.getListData); + stop(); + $.ajax({ + url: '/presetStore', + method: 'get', + data: { + filter: { + year: 2013, + modelId: 1 + } + }, + dataType: 'json' + }).then(function (response) { + equal(response.data[0].id, 1, 'got the first item'); + equal(response.data.length, 1, 'only got one item'); + start(); + }); + }); + QUnit.test('posting an empty data object', function (assert) { + var done = assert.async(); + fixture('/data', function (req, res) { + if (req.data == null) { + throw new Error('req.data should be an empty object'); + } else { + return {}; + } + }); + var def = $.ajax({ + method: 'post', + url: '/data', + dataType: 'json', + data: {} + }); + def.then(function () { + assert.ok(true, 'works!'); + done(); + }, function (e) { + assert.notOk(e, 'should not fail'); + }); + }); + test('store with objects allows .create, .update and .destroy (#1471)', 4, function () { + var store = fixture.store([ + { + id: 1, + modelId: 1, + year: 2013, + name: '2013 Mustang', + thumb: 'http://mustangsdaily.com/blog/wp-content/uploads/2012/07/01-2013-ford-mustang-gt-review-585x388.jpg' + }, + { + id: 2, + modelId: 1, + year: 2014, + name: '2014 Mustang', + thumb: 'http://mustangsdaily.com/blog/wp-content/uploads/2013/03/2014-roush-mustang.jpg' + }, + { + id: 3, + modelId: 2, + year: 2013, + name: '2013 Focus', + thumb: 'http://images.newcars.com/images/car-pictures/original/2013-Ford-Focus-Sedan-S-4dr-Sedan-Exterior.png' + }, + { + id: 4, + modelId: 2, + year: 2014, + name: '2014 Focus', + thumb: 'http://ipinvite.iperceptions.com/Invitations/survey705/images_V2/top4.jpg' + }, + { + id: 5, + modelId: 3, + year: 2013, + name: '2013 Altima', + thumb: 'http://www.blogcdn.com/www.autoblog.com/media/2012/04/04-2013-nissan-altima-1333416664.jpg' + }, + { + id: 6, + modelId: 3, + year: 2014, + name: '2014 Altima', + thumb: 'http://www.blogcdn.com/www.autoblog.com/media/2012/04/01-2013-nissan-altima-ny.jpg' + }, + { + id: 7, + modelId: 4, + year: 2013, + name: '2013 Leaf', + thumb: 'http://www.blogcdn.com/www.autoblog.com/media/201204/01-2013-nissan-altima-ny.jpg' + }, + { + id: 8, + modelId: 4, + year: 2014, + name: '2014 Leaf', + thumb: 'http://images.thecarconnection.com/med/2013-nissan-leaf_100414473_m.jpg' + } + ]); + fixture('GET /cars', store.getListData); + fixture('POST /cars', store.createData); + fixture('PUT /cars/{id}', store.updateData); + fixture('DELETE /cars/{id}', store.destroyData); + var findAll = function () { + return $.ajax({ + url: '/cars', + dataType: 'json' + }); + }; + stop(); + findAll().then(function (carsData) { + equal(carsData.data.length, 8, 'Got all cars'); + return $.ajax({ + url: '/cars/' + carsData.data[1].id, + method: 'DELETE', + dataType: 'json' + }); + }).then(function () { + return findAll(); + }).then(function (carsData) { + equal(carsData.data.length, 7, 'One car less'); + equal(carsData.data[1].name, '2013 Focus', 'Car actually deleted'); + }).then(function () { + return $.ajax({ + url: '/cars', + method: 'post', + dataType: 'json', + data: { + modelId: 3, + year: 2015, + name: '2015 Altima' + } + }); + }).then(function (saved) { + return $.ajax({ + url: '/cars/' + saved.id, + method: 'put', + dataType: 'json', + data: { + modelId: 3, + year: 2015, + name: '2015 Nissan Altima' + } + }); + }).then(function (updated) { + return findAll(); + }).then(function (cars) { + equal(cars.data.length, 8, 'New car created'); + start(); + }); + }); + test('filtering works', function () { + var next; + var store = fixture.store([ + { + state: 'CA', + name: 'Casadina' + }, + { + state: 'NT', + name: 'Alberny' + } + ], new QueryLogic({ identity: ['state'] })); + fixture({ 'GET /api/cities': store.getListData }); + stop(); + $.getJSON('/api/cities?filter[state]=CA').then(function (data) { + deepEqual(data, { + data: [{ + state: 'CA', + name: 'Casadina' + }], + count: 1 + }); + QUnit.start(); + }, function (e) { + ok(false, '' + e); + start(); + }); + }); + test('filtering works with nested props', function () { + QUnit.stop(); + var store = fixture.store([ + { + id: 1, + name: 'Cheese City', + slug: 'cheese-city', + address: { + city: 'Casadina', + state: 'CA' + } + }, + { + id: 2, + name: 'Crab Barn', + slug: 'crab-barn', + address: { + city: 'Alberny', + state: 'NT' + } + } + ]); + fixture({ 'GET /restaurants': store.getListData }); + $.getJSON('/api/restaurants?filter[address][city]=Alberny').then(function (responseData) { + deepEqual(responseData, { + count: 1, + data: [{ + id: 2, + name: 'Crab Barn', + slug: 'crab-barn', + address: { + city: 'Alberny', + state: 'NT' + } + }] + }); + QUnit.start(); + }, function (e) { + ok(false); + start(); + }); + }); + test('filtering works with nested.props', function () { + QUnit.stop(); + var store = fixture.store([ + { + id: 1, + name: 'Cheese City', + slug: 'cheese-city', + address: { + city: 'Casadina', + state: 'CA' + } + }, + { + id: 2, + name: 'Crab Barn', + slug: 'crab-barn', + address: { + city: 'Alberny', + state: 'NT' + } + } + ]); + store.connection.getListData({ filter: { 'address.city': 'Alberny' } }).then(function (responseData) { + deepEqual(responseData, { + count: 1, + data: [{ + id: 2, + name: 'Crab Barn', + slug: 'crab-barn', + address: { + city: 'Alberny', + state: 'NT' + } + }] + }); + QUnit.start(); + }); + }); + QUnit.test('onreadystatechange, event is passed', function () { + fixture('GET something', function () { + return {}; + }); + var xhr = new XMLHttpRequest(); + xhr.open('GET', 'something'); + xhr.onreadystatechange = function (ev) { + ok(ev.target != null, 'the event object passed to onreadystatechange'); + start(); + }; + xhr.send(); + stop(); + }); + if (__dirname !== '/') { + asyncTest('doesn\'t break onreadystatechange (#3)', function () { + var url = __dirname + '/fixtures/test.json'; + var xhr = new XMLHttpRequest(); + xhr.onreadystatechange = function () { + if (xhr.readyState === 4) { + ok(true, 'we made a successful request'); + start(); + } + }; + xhr.open('GET', url); + xhr.send(); + }); + } + QUnit.module('XHR Shim'); + test('Supports onload', function () { + var xhr = new XMLHttpRequest(); + QUnit.ok('onload' in xhr, 'shim passes onload detection'); + }); + if (__dirname !== '/') { + asyncTest('supports addEventListener on XHR shim', function () { + var url = __dirname + '/fixtures/test.json'; + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + ok(true, 'our shim supports addEventListener'); + start(); + }); + xhr.open('GET', url); + xhr.send(); + }); + } + if (__dirname !== '/') { + asyncTest('supports removeEventListener on XHR shim', function () { + var url = __dirname + '/fixtures/test.json'; + var xhr = new XMLHttpRequest(); + var onload = function () { + ok(false, 'this should not be called'); + }; + xhr.addEventListener('load', onload); + xhr.removeEventListener('load', onload); + xhr.onload = function () { + setTimeout(function () { + ok(true, 'didn\'t call the event listener'); + start(); + }); + }; + xhr.open('GET', url); + xhr.send(); + }); + } + test('supports setDisableHeaderCheck', function () { + var xhr = new XMLHttpRequest(); + try { + xhr.setDisableHeaderCheck(true); + ok(true, 'did not throw'); + } catch (e) { + ok(false, 'do not support setDisableHeaderCheck'); + } + }); + if (__dirname !== '/') { + asyncTest('supports setRequestHeader', function () { + var url = __dirname + '/fixtures/test.json'; + var xhr = new XMLHttpRequest(); + xhr.setRequestHeader('foo', 'bar'); + xhr.onreadystatechange = function () { + if (xhr.readyState === 4) { + equal(xhr._requestHeaders.foo, 'bar', 'header was set'); + start(); + } + }; + xhr.open('GET', url); + xhr.send(); + }); + } + if (__dirname !== '/') { + asyncTest('supports getResponseHeader', function () { + var url = __dirname + '/fixtures/test.json'; + var xhr = new XMLHttpRequest(); + xhr.onreadystatechange = function () { + if (xhr.readyState === 4) { + var header = xhr.getResponseHeader('Content-Type'); + ok(header.indexOf('application/json') >= 0, 'got correct header back'); + start(); + } + }; + xhr.open('GET', url); + xhr.send(); + }); + } + asyncTest('supports getAllResponseHeaders', function () { + fixture('GET something', function (req, res) { + res(200, { message: 'this is the body' }, { foo: 'bar' }); + }); + var xhr = new XMLHttpRequest(); + xhr.onreadystatechange = function () { + if (xhr.readyState === 4) { + var headers = xhr.getAllResponseHeaders(); + var parsed = parseHeaders(headers); + ok(typeof headers === 'string', 'got headers back'); + ok(parsed.foo === 'bar', 'got proper values'); + start(); + } + }; + xhr.open('GET', 'something'); + xhr.send(); + }); + asyncTest('pass data to response handler (#13)', function () { + fixture('GET something', function (req, res) { + res(403, { message: 'No bad guys' }); + }); + var xhr = new XMLHttpRequest(); + xhr.open('GET', 'something'); + xhr.onreadystatechange = function (ev) { + deepEqual(JSON.parse(this.responseText), { message: 'No bad guys' }, 'correct response'); + equal(this.status, 403, 'correct status'); + start(); + }; + xhr.send(); + }); + asyncTest('pass return value for fixture', function () { + fixture('GET something', { foo: 'bar' }); + var xhr = new XMLHttpRequest(); + xhr.open('GET', 'something'); + xhr.onreadystatechange = function (ev) { + deepEqual(JSON.parse(this.responseText), { foo: 'bar' }, 'correct response'); + equal(this.status, 200, 'correct status'); + start(); + }; + xhr.send(); + }); + if (__dirname !== '/') { + asyncTest('pass headers in fallthrough', function () { + var url = __dirname + '/fixtures/foobar.json'; + var xhr = new XMLHttpRequest(); + expect(2); + xhr.open('GET', url); + xhr.setRequestHeader('foo', 'bar'); + xhr.onreadystatechange = function (ev) { + var originalXhr = ev.target; + if (originalXhr.readyState === 1) { + originalXhr.setRequestHeader = function (key, val) { + equal(key, 'foo'); + equal(val, 'bar'); + }; + } + if (originalXhr.readyState === 4) { + start(); + } + }; + xhr.send(); + }); + } + test('first set.Algebra CRUD works (#12)', 5, function () { + var algebra = new set.Algebra(new set.Translate('where', 'where'), set.props.id('_id'), set.props.sort('orderBy'), set.props.enum('type', [ + 'used', + 'new', + 'certified' + ]), set.props.rangeInclusive('start', 'end')); + var store = fixture.store([ + { + _id: 1, + modelId: 1, + year: 2013, + name: '2013 Mustang', + type: 'used' + }, + { + _id: 2, + modelId: 1, + year: 2014, + name: '2014 Mustang', + type: 'new' + }, + { + _id: 3, + modelId: 2, + year: 2013, + name: '2013 Focus', + type: 'used' + }, + { + _id: 4, + modelId: 2, + year: 2014, + name: '2014 Focus', + type: 'certified' + }, + { + _id: 5, + modelId: 3, + year: 2013, + name: '2013 Altima', + type: 'used' + }, + { + _id: 6, + modelId: 3, + year: 2014, + name: '2014 Altima', + type: 'certified' + }, + { + _id: 7, + modelId: 4, + year: 2013, + name: '2013 Leaf', + type: 'used' + }, + { + _id: 8, + modelId: 4, + year: 2014, + name: '2014 Leaf', + type: 'used' + } + ], algebra); + fixture('GET /cars', store.getListData); + fixture('POST /cars', store.createData); + fixture('PUT /cars/{_id}', store.updateData); + fixture('DELETE /cars/{_id}', store.destroyData); + fixture('GET /cars/{_id}', store.getData); + var findAll = function () { + return $.ajax({ + url: '/cars', + dataType: 'json' + }); + }; + stop(); + findAll().then(function (carsData) { + equal(carsData.data.length, 8, 'Got all cars'); + return $.ajax({ + url: '/cars/' + carsData.data[1]._id, + method: 'DELETE', + dataType: 'json' + }); + }).then(function () { + return findAll(); + }).then(function (carsData) { + equal(carsData.data.length, 7, 'One car less'); + equal(carsData.data[1].name, '2013 Focus', 'Car actually deleted'); + }).then(function () { + return $.ajax({ + url: '/cars', + method: 'post', + dataType: 'json', + data: { + modelId: 3, + year: 2015, + name: '2015 Altima', + type: 'new' + } + }); + }).then(function (saved) { + return $.ajax({ + url: '/cars/' + saved._id, + method: 'put', + dataType: 'json', + data: { + modelId: 3, + year: 2015, + name: '2015 Nissan Altima' + } + }); + }).then(function (updated) { + return findAll(); + }).then(function (cars) { + equal(cars.data.length, 8, 'New car created'); + return $.ajax({ + url: '/cars/5', + method: 'get', + dataType: 'json' + }); + }).then(function (car) { + equal(car.name, '2013 Altima', 'get a single car works'); + start(); + }); + }); + test('set.Algebra CRUD works (#12)', 5, function () { + var algebra = new set.Algebra(new set.Translate('where', 'where'), set.props.id('_id'), set.props.sort('orderBy'), set.props.enum('type', [ + 'used', + 'new', + 'certified' + ]), set.props.rangeInclusive('start', 'end')); + var store = fixture.store([ + { + _id: 1, + modelId: 1, + year: 2013, + name: '2013 Mustang', + type: 'used' + }, + { + _id: 2, + modelId: 1, + year: 2014, + name: '2014 Mustang', + type: 'new' + }, + { + _id: 3, + modelId: 2, + year: 2013, + name: '2013 Focus', + type: 'used' + }, + { + _id: 4, + modelId: 2, + year: 2014, + name: '2014 Focus', + type: 'certified' + }, + { + _id: 5, + modelId: 3, + year: 2013, + name: '2013 Altima', + type: 'used' + }, + { + _id: 6, + modelId: 3, + year: 2014, + name: '2014 Altima', + type: 'certified' + }, + { + _id: 7, + modelId: 4, + year: 2013, + name: '2013 Leaf', + type: 'used' + }, + { + _id: 8, + modelId: 4, + year: 2014, + name: '2014 Leaf', + type: 'used' + } + ], algebra); + fixture('GET /cars', store.getListData); + fixture('POST /cars', store.createData); + fixture('PUT /cars/{_id}', store.updateData); + fixture('DELETE /cars/{_id}', store.destroyData); + fixture('GET /cars/{_id}', store.getData); + var findAll = function () { + return $.ajax({ + url: '/cars', + dataType: 'json' + }); + }; + stop(); + findAll().then(function (carsData) { + equal(carsData.data.length, 8, 'Got all cars'); + return $.ajax({ + url: '/cars/' + carsData.data[1]._id, + method: 'DELETE', + dataType: 'json' + }); + }).then(function () { + return findAll(); + }).then(function (carsData) { + equal(carsData.data.length, 7, 'One car less'); + equal(carsData.data[1].name, '2013 Focus', 'Car actually deleted'); + }).then(function () { + return $.ajax({ + url: '/cars', + method: 'post', + dataType: 'json', + data: { + modelId: 3, + year: 2015, + name: '2015 Altima', + type: 'new' + } + }); + }).then(function (saved) { + return $.ajax({ + url: '/cars/' + saved._id, + method: 'put', + dataType: 'json', + data: { + modelId: 3, + year: 2015, + name: '2015 Nissan Altima' + } + }); + }).then(function (updated) { + return findAll(); + }).then(function (cars) { + equal(cars.data.length, 8, 'New car created'); + return $.ajax({ + url: '/cars/5', + method: 'get', + dataType: 'json' + }); + }).then(function (car) { + equal(car.name, '2013 Altima', 'get a single car works'); + start(); + }); + }); + asyncTest('set.Algebra clauses work', function () { + var NumberValue = matches.makeComparatorType(function (a, b) { + if (a === b) { + return true; + } + if (a && b) { + return +a === +b; + } + return false; + }); + var algebra = new set.Algebra(new set.Translate('where', 'where'), set.props.id('_id'), set.props.sort('orderBy'), set.props.enum('type', [ + 'used', + 'new', + 'certified' + ]), set.props.rangeInclusive('start', 'end'), { + schema: function (schema) { + schema.keys.year = NumberValue; + } + }); + var store = fixture.store([ + { + _id: 1, + modelId: 1, + year: 2013, + name: '2013 Mustang', + type: 'used' + }, + { + _id: 2, + modelId: 1, + year: 2014, + name: '2014 Mustang', + type: 'new' + }, + { + _id: 3, + modelId: 2, + year: 2013, + name: '2013 Focus', + type: 'used' + }, + { + _id: 4, + modelId: 2, + year: 2014, + name: '2014 Focus', + type: 'certified' + }, + { + _id: 5, + modelId: 3, + year: 2013, + name: '2013 Altima', + type: 'used' + }, + { + _id: 6, + modelId: 3, + year: 2014, + name: '2014 Altima', + type: 'certified' + }, + { + _id: 7, + modelId: 4, + year: 2013, + name: '2013 Leaf', + type: 'used' + }, + { + _id: 8, + modelId: 4, + year: 2014, + name: '2014 Leaf', + type: 'used' + } + ], algebra); + fixture('GET /cars', store.getListData); + $.ajax({ + url: '/cars?where[year]=2013', + dataType: 'json' + }).then(function (carsData) { + equal(carsData.data.length, 4, 'Where clause works with numbers'); + return $.ajax({ + url: '/cars?where[year]=2013&orderBy=name', + dataType: 'json' + }); + }).then(function (carsData) { + var names = carsData.data.map(function (c) { + return c.name; + }); + deepEqual(names, [ + '2013 Altima', + '2013 Focus', + '2013 Leaf', + '2013 Mustang' + ], 'sort works'); + return $.ajax({ + url: '/cars?where[year]=2013&orderBy=name&start=1&end=2', + dataType: 'json' + }); + }).then(function (carsData) { + var names = carsData.data.map(function (c) { + return c.name; + }); + deepEqual(names, [ + '2013 Focus', + '2013 Leaf' + ], 'pagination works'); + start(); + }); + }); + test('storeConnection reset', function () { + var algebra = new set.Algebra(new set.Translate('where', 'where'), set.props.id('_id')); + var store = fixture.store([ + { + _id: 1, + modelId: 1, + year: 2013, + name: '2013 Mustang', + type: 'used' + }, + { + _id: 2, + modelId: 1, + year: 2014, + name: '2014 Mustang', + type: 'new' + } + ], algebra); + fixture('GET /cars', store.getListData); + fixture('POST /cars', store.createData); + fixture('PUT /cars/{_id}', store.updateData); + fixture('DELETE /cars/{_id}', store.destroyData); + fixture('GET /cars/{_id}', store.getData); + var findAll = function () { + return $.ajax({ + url: '/cars', + dataType: 'json' + }); + }; + $.ajax({ + url: '/cars/1', + method: 'DELETE', + dataType: 'json' + }).then(function () { + store.reset(); + return findAll(); + }).then(function (carsData) { + equal(carsData.data.length, 2, 'Got all cars'); + start(); + }); + stop(); + }); + function makeAlgebraTest(fixtureUrl) { + return function () { + var algebra = new set.Algebra(new set.Translate('where', 'where'), set.props.id('_id'), set.props.sort('orderBy'), set.props.enum('type', [ + 'used', + 'new', + 'certified' + ]), set.props.rangeInclusive('start', 'end')); + var store = fixture.store([ + { + _id: 1, + modelId: 1, + year: 2013, + name: '2013 Mustang', + type: 'used' + }, + { + _id: 2, + modelId: 1, + year: 2014, + name: '2014 Mustang', + type: 'new' + }, + { + _id: 3, + modelId: 2, + year: 2013, + name: '2013 Focus', + type: 'used' + }, + { + _id: 4, + modelId: 2, + year: 2014, + name: '2014 Focus', + type: 'certified' + }, + { + _id: 5, + modelId: 3, + year: 2013, + name: '2013 Altima', + type: 'used' + }, + { + _id: 6, + modelId: 3, + year: 2014, + name: '2014 Altima', + type: 'certified' + }, + { + _id: 7, + modelId: 4, + year: 2013, + name: '2013 Leaf', + type: 'used' + }, + { + _id: 8, + modelId: 4, + year: 2014, + name: '2014 Leaf', + type: 'used' + } + ], algebra); + fixture(fixtureUrl, store); + var findAll = function () { + return $.ajax({ + url: '/cars', + dataType: 'json' + }); + }; + stop(); + findAll().then(function (carsData) { + equal(carsData.data.length, 8, 'Got all cars'); + return $.ajax({ + url: '/cars/' + carsData.data[1]._id, + method: 'DELETE', + dataType: 'json' + }); + }).then(function () { + return findAll(); + }).then(function (carsData) { + equal(carsData.data.length, 7, 'One car less'); + equal(carsData.data[1].name, '2013 Focus', 'Car actually deleted'); + }).then(function () { + return $.ajax({ + url: '/cars', + method: 'post', + dataType: 'json', + data: { + modelId: 3, + year: 2015, + name: '2015 Altima', + type: 'new' + } + }); + }).then(function (saved) { + return $.ajax({ + url: '/cars/' + saved._id, + method: 'put', + dataType: 'json', + data: { + modelId: 3, + year: 2015, + name: '2015 Nissan Altima' + } + }); + }).then(function (updated) { + return findAll(); + }).then(function (cars) { + equal(cars.data.length, 8, 'New car created'); + return $.ajax({ + url: '/cars/5', + method: 'get', + dataType: 'json' + }); + }).then(function (car) { + equal(car.name, '2013 Altima', 'get a single car works'); + start(); + }); + }; + } + test('set.Algebra CRUD works with easy hookup (#12)', 5, makeAlgebraTest('/cars/{_id}')); + test('set.Algebra CRUD works with easy hookup and list-style url (#52)', 5, makeAlgebraTest('/cars')); + test('store.getList and store.get', function () { + var algebra = new set.Algebra(set.props.id('_id')); + var store = fixture.store([ + { + _id: 1, + modelId: 1, + year: 2013, + name: '2013 Mustang', + type: 'used' + }, + { + _id: 2, + modelId: 1, + year: 2014, + name: '2014 Mustang', + type: 'new' + }, + { + _id: 3, + modelId: 2, + year: 2013, + name: '2013 Focus', + type: 'used' + }, + { + _id: 4, + modelId: 2, + year: 2014, + name: '2014 Focus', + type: 'certified' + }, + { + _id: 5, + modelId: 3, + year: 2013, + name: '2013 Altima', + type: 'used' + }, + { + _id: 6, + modelId: 3, + year: 2014, + name: '2014 Altima', + type: 'certified' + }, + { + _id: 7, + modelId: 4, + year: 2013, + name: '2013 Leaf', + type: 'used' + }, + { + _id: 8, + modelId: 4, + year: 2014, + name: '2014 Leaf', + type: 'used' + } + ], algebra); + equal(store.getList({ year: 2013 }).data.length, 4, 'filtered'); + deepEqual(store.get({ _id: 5 }).name, '2013 Altima', 'get'); + }); + asyncTest('supports addEventListener on shim using fixture', function () { + fixture('/addEventListener', function () { + return {}; + }); + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + ok(true, 'our shim supports addEventListener'); + start(); + }); + xhr.open('GET', '/addEventListener'); + xhr.send(); + }); + if (__dirname !== '/') { + test('supports sync on XHR shim (#23)', function () { + var url = __dirname + '/fixtures/test.json'; + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + ok(true, 'our shim supports addEventListener'); + }); + xhr.open('GET', url, false); + xhr.send(); + }); + } + test('supports sync fixtures (#23)', function () { + fixture('/sync', function () { + return {}; + }); + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + ok(true, 'our shim supports sync'); + }); + xhr.open('GET', '/sync', false); + xhr.send(); + }); + if (__dirname !== '/') { + test('supports sync redirect fixtures (#23)', function () { + fixture('/sync_redirect', __dirname + '/fixtures/test.json'); + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + ok(true, 'our shim supports sync redirect'); + }); + xhr.open('GET', '/sync_redirect', false); + xhr.send(); + }); + } + if (__dirname !== '/') { + asyncTest('slow mode works (#26)', function () { + var url = __dirname + '/fixtures/test.json'; + fixture({ url: url }, 1000); + var xhr = new XMLHttpRequest(); + var startTime = new Date(); + xhr.addEventListener('load', function () { + var delay = new Date() - startTime; + ok(delay >= 900, delay + 'ms >= 900ms'); + fixture({ url: url }, null); + start(); + }); + xhr.open('GET', url); + xhr.send(); + }); + } + asyncTest('onload should be triggered for HTTP error responses (#36)', function () { + fixture('/onload', function (req, res) { + res(400); + }); + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + ok(true, 'onload should be invoked'); + fixture('/onload', null); + start(); + }); + xhr.addEventListener('error', function () { + ok(false, 'onerror should not be invoked'); + fixture('/onload', null); + start(); + }); + xhr.open('GET', '/onload'); + xhr.send(); + }); + asyncTest('responseText & responseXML should not be set for arraybuffer types (#38)', function () { + fixture('/onload', '/test/fixtures/foo.json'); + var oldError = window.onerror; + window.onerror = function (msg, url, line) { + ok(false, 'There should not be an error'); + start(); + }; + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + fixture('/onload', null); + window.onerror = oldError; + ok(true, 'Got here without an error'); + start(); + }); + xhr.responseType = 'arraybuffer'; + xhr.open('GET', '/onload'); + xhr.send(); + }); + asyncTest('fixture with timeout does not run if $.ajax timeout less than delay', function () { + var delay = fixture.delay; + fixture.delay = 1000; + fixture('/onload', function () { + fixture('/onload', null); + ok(false, 'timed out xhr did not abort'); + start(); + }); + $.ajax({ + url: '/onload', + timeout: 50, + error: function (xhr) { + fixture('/onload', null); + ok(true, 'Got to the error handler'); + equal(xhr.statusText, 'timeout'); + equal(xhr.status, '0'); + start(); + } + }); + fixture.delay = delay; + }); + asyncTest('response headers are set', function () { + fixture('GET /todos', function (request, response) { + response(200, '{}', { foo: 'bar' }); + }); + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + var headers = parseHeaders(xhr.getAllResponseHeaders()); + ok(headers.foo === 'bar', 'header was set'); + start(); + }); + xhr.open('GET', '/todos'); + xhr.send(); + }); + asyncTest('match values in get data', function () { + fixture({ + method: 'GET', + url: '/data-value', + data: { name: 'justin' } + }, function (request, response) { + QUnit.ok(true, 'got it'); + return {}; + }); + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + QUnit.start(); + }); + xhr.open('GET', '/data-value?name=justin&age=22'); + xhr.send(); + }); + asyncTest('universal match (#2000)', function () { + fixture({}, function () { + ok(true, 'got hit'); + return {}; + }); + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + QUnit.start(); + fixture.fixtures.splice(0, fixture.fixtures.length); + }); + xhr.open('GET', '/something-totally-unexpected-62'); + xhr.send(); + }); + test('set.Algebra stores provide a count (#58)', function () { + var algebra = new set.Algebra(new set.Translate('where', 'where'), set.props.id('_id'), set.props.sort('orderBy'), set.props.enum('type', [ + 'used', + 'new', + 'certified' + ]), set.props.rangeInclusive('start', 'end')); + var store = fixture.store([ + { + _id: 1, + modelId: 1, + year: 2013, + name: '2013 Mustang', + type: 'used' + }, + { + _id: 2, + modelId: 1, + year: 2014, + name: '2014 Mustang', + type: 'new' + }, + { + _id: 3, + modelId: 2, + year: 2013, + name: '2013 Focus', + type: 'used' + }, + { + _id: 4, + modelId: 2, + year: 2014, + name: '2014 Focus', + type: 'certified' + }, + { + _id: 5, + modelId: 3, + year: 2013, + name: '2013 Altima', + type: 'used' + }, + { + _id: 6, + modelId: 3, + year: 2014, + name: '2014 Altima', + type: 'certified' + }, + { + _id: 7, + modelId: 4, + year: 2013, + name: '2013 Leaf', + type: 'used' + }, + { + _id: 8, + modelId: 4, + year: 2014, + name: '2014 Leaf', + type: 'used' + } + ], algebra); + fixture('/cars/{_id}', store); + stop(); + $.ajax({ + url: '/cars', + dataType: 'json', + data: { + start: 2, + end: 3 + } + }).then(function (carsData) { + equal(carsData.data.length, 2, 'Got 2 cars'); + equal(carsData.count, 8, 'got the count'); + QUnit.start(); + }, function () { + QUnit.ok(false, 'borked'); + QUnit.start(); + }); + }); + asyncTest('should allow Arrays as data type (#133)', function () { + fixture('/array-data', function (req, res) { + ok(req.data instanceof Array, 'data returned should be instance of Array'); + return {}; + }); + var data = []; + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + fixture('/array-data', null); + ok(true, 'should not throw when sending Array'); + start(); + }); + xhr.open('GET', '/array-data'); + xhr.send(data); + }); + asyncTest('should allow FormData as data type (#133)', function () { + fixture('/upload', function (req, res) { + ok(req.data instanceof FormData, 'data returned should be instance of formdata'); + res(400); + }); + var data = new FormData(); + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + fixture('/upload', null); + ok(true, 'should not throw when sending FormData'); + start(); + }); + xhr.open('POST', '/upload', true); + xhr.send(data); + }); + if ('onabort' in XMLHttpRequest._XHR.prototype) { + asyncTest('fixture with timeout aborts if xhr timeout less than delay', function () { + fixture('/onload', 1000); + var xhr = new XMLHttpRequest(); + xhr.open('GET', '/onload'); + xhr.send(); + setTimeout(function () { + xhr.abort(); + }, 50); + xhr.addEventListener('abort', function () { + fixture('/onload', null); + ok(true, 'Got to the error handler'); + equal(xhr.statusText, ''); + equal(xhr.status, 0); + start(); + }); + xhr.addEventListener('load', function () { + fixture('/onload', null); + ok(false, 'timed out xhr did not abort'); + start(); + }); + }); + asyncTest('dynamic fixture with timeout does not run if xhr timeout less than delay', function () { + var delay = fixture.delay; + fixture.delay = 1000; + fixture('/onload', function () { + fixture('/onload', null); + ok(false, 'timed out xhr did not abort'); + start(); + }); + var xhr = new XMLHttpRequest(); + xhr.open('GET', '/onload'); + setTimeout(function () { + xhr.abort(); + }, 50); + xhr.send(); + xhr.addEventListener('abort', function () { + fixture('/onload', null); + ok(true, 'Got to the error handler'); + equal(xhr.statusText, ''); + equal(xhr.status, 0); + start(); + }); + fixture.delay = delay; + }); + test('abort() sets readyState correctly', function () { + stop(); + fixture('/foo', function () { + return {}; + }); + var xhr = new XMLHttpRequest(); + xhr.open('GET', '/foo'); + xhr.addEventListener('abort', function () { + fixture('/foo', null); + ok(true, 'Got to the error handler'); + equal(xhr.status, 0); + equal(xhr.statusText, ''); + setTimeout(function () { + equal(xhr.readyState, 0); + start(); + }, 50); + }); + xhr.send(); + xhr.abort(); + }); + test('abort() of already completed fixture', function () { + stop(); + fixture('/foo', function () { + return {}; + }); + var xhr = new XMLHttpRequest(); + xhr.open('GET', '/foo'); + xhr.addEventListener('load', function () { + fixture('/foo', null); + equal(xhr.readyState, 4); + xhr.abort(); + start(); + }); + xhr.send(); + }); + asyncTest('should be able to call getResponseHeader onload', function () { + fixture('/onload', function (req, res) { + res(400); + }); + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + fixture('/onload', null); + xhr.getResponseHeader('Set-Cookie'); + ok(true, 'should not throw when calling getResponseHeader'); + start(); + }); + xhr.open('GET', '/onload'); + xhr.send(); + }); + testHelpers.dev.devOnlyTest('Works with steal-clone', function () { + steal.loader.import('steal-clone', { name: 'can-fixture' }).then(function (clone) { + clone({})['import']('can-fixture').then(function (fixture) { + fixture('/onload', function (req, res) { + res(400); + }); + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + fixture('/onload', null); + QUnit.ok(true, 'Got to the load event without throwing'); + start(); + }); + xhr.open('GET', '/onload'); + xhr.send(); + }); + }); + stop(); + }); + } + }('/', require, exports, module)); +}); +/*can-fixture-socket@2.0.0#src/store*/ +define('can-fixture-socket@2.0.0#src/store', [ + 'require', + 'exports', + 'module', + 'can-fixture/core' +], function (require, exports, module) { + var extractResponse = require('can-fixture/core').extractResponse; + function requestHandlerToListener(method) { + return function (query, fn) { + var req = { data: query }; + var res = function () { + var response = extractResponse.apply(null, arguments); + if (response[0] === 200) { + fn(null, response[1]); + } else { + fn(response[1]); + } + }; + method(req, res); + }; + } + function storeToListeners(fixtureStore) { + var methods = [ + 'getListData', + 'getData', + 'updateData', + 'createData', + 'destroyData' + ]; + return methods.reduce(function (listeners, method) { + listeners[method] = requestHandlerToListener(fixtureStore[method]); + return listeners; + }, {}); + } + module.exports = { + requestHandlerToListener: requestHandlerToListener, + storeToListeners: storeToListeners + }; +}); +/*can-fixture-socket@2.0.0#src/feathers-client*/ +define('can-fixture-socket@2.0.0#src/feathers-client', [ + 'require', + 'exports', + 'module', + './store', + 'can-assign' +], function (require, exports, module) { + var storeToListeners = require('./store').storeToListeners; + var assign = require('can-assign'); + function subscribeFeathersStoreToServer(serviceName, fixtureStore, mockServer, options) { + var listeners = storeToListeners(fixtureStore); + mockServer.on(serviceName + '::find', toFeathersDataHandler(listeners.getListData, null, toFeathersFind)); + mockServer.on(serviceName + '::get', toFeathersDataHandler(listeners.getData, wrapToId(options), null)); + mockServer.on(serviceName + '::remove', toFeathersRemoveHandler(listeners.getData, listeners.destroyData, options)); + mockServer.on(serviceName + '::create', toFeathersCreateHandler(listeners.createData)); + mockServer.on(serviceName + '::update', toFeathersUpdateHandler(listeners.updateData, options)); + } + function toFeathersDataHandler(method, queryTransformer, dataTransformer) { + return function (query) { + var args = Array.prototype.slice.call(arguments), fn; + if (typeof args[args.length - 1] === 'function') { + fn = args[args.length - 1]; + } + query = queryTransformer ? queryTransformer(query) : query; + method(query, function (err, data) { + if (err) { + fn && fn(err); + } else { + data = dataTransformer ? dataTransformer(data) : data; + fn && fn(null, data); + } + }); + }; + } + function wrapToId(options) { + return function (id) { + var o = {}, idProp = options && options.id || 'id'; + o[idProp] = id; + return o; + }; + } + function toFeathersFind(data) { + return { + total: data.count, + limit: data.limit, + skip: data.offset, + data: data.data + }; + } + function toFeathersRemoveHandler(getData, destroyData, options) { + return function (id, query, fn) { + var setQuery = wrapToId(options)(id); + getData(setQuery, function (err, item) { + if (err) { + fn(err); + } else { + destroyData(setQuery, function (err, data) { + if (err) { + fn(err); + } else { + fn(null, item); + } + }); + } + }); + }; + } + function toFeathersUpdateHandler(updateData, options) { + return function (id, data, query, fn) { + var setQuery = wrapToId(options)(id); + updateData(assign(setQuery, data), function (err, data2) { + if (err) { + fn(err); + } else { + fn(null, assign(setQuery, assign(data, data2))); + } + }); + }; + } + function toFeathersCreateHandler(createData) { + return function (data, query, fn) { + createData(data, function (err, data2) { + if (err) { + fn(err); + } else { + fn(null, assign(data, data2)); + } + }); + }; + } + module.exports = { subscribeFeathersStoreToServer: subscribeFeathersStoreToServer }; +}); +/*can-fixture-socket@2.0.0#src/index*/ +define('can-fixture-socket@2.0.0#src/index', [ + 'require', + 'exports', + 'module', + './feathers-client' +], function (require, exports, module) { + var subscribeFeathersStoreToServer = require('./feathers-client').subscribeFeathersStoreToServer; + var MockedServer = function (io) { + this.io = io; + this.events = {}; + this.subscribers = {}; + resetManagerCache(io.managers); + this.origs = mockManager(io.Manager.prototype, this); + }; + MockedServer.prototype.on = function (event, cb) { + var self = this; + var events = {}; + if (typeof event === 'string') { + events[event] = cb; + } + if (typeof event === 'object') { + events = event; + } + Object.keys(events).forEach(function (name) { + sub(self.events, name, events[name]); + }); + }; + MockedServer.prototype.emit = function (event) { + var dataArgs = Array.prototype.slice.call(arguments, 1); + pub(this.subscribers, event, dataArgs); + }; + MockedServer.prototype.onFeathersService = function (serviceName, fixtureStore, options) { + subscribeFeathersStoreToServer(serviceName, fixtureStore, this, options); + }; + MockedServer.prototype.restore = function () { + restoreManager(this.io.Manager.prototype, this.origs); + resetManagerCache(this.io.managers); + }; + var MockedSocket = function (server) { + this._server = server; + this.io = { engine: this }; + }; + MockedSocket.prototype = { + on: function (event, cb) { + debug('MockedSocket.on ... ' + event); + sub(this._server.subscribers, event, cb); + }, + emit: function (event) { + var dataArgs = Array.prototype.slice.call(arguments, 1); + debug('MockedSocket.emit ...' + event); + pub(this._server.events, event, dataArgs); + }, + once: function () { + debug('MockedSocket.once ...'); + }, + off: function (event, cb) { + debug('MockedSocket.off ... ' + event); + unsub(this._server.subscribers, event, cb); + }, + open: function () { + return this.connect(); + }, + connect: function () { + this.connected = true; + this.disconnected = false; + }, + close: function () { + return this.disconnect(); + }, + disconnect: function () { + this.connected = false; + this.disconnected = true; + } + }; + function pub(pubsub, event, dataArgs) { + debug(' >>> pub ' + event); + var subscribers = pubsub[event] || []; + subscribers.forEach(function (subscriber) { + subscriber.apply(null, dataArgs); + }); + } + function sub(pubsub, event, cb) { + debug(' <<< sub ' + event); + if (!pubsub[event]) { + pubsub[event] = []; + } + pubsub[event].push(cb); + } + function unsub(pubsub, event, cb) { + debug(' <<< unsub ' + event); + pubsub[event].forEach(function (registeredCb, index) { + if (registeredCb === cb) { + pubsub[event].splice(index, 1); + } + }); + } + function mockManager(managerProto, server) { + var methods = [ + 'open', + 'socket' + ]; + var origs = methods.map(function (name) { + return { + name: name, + method: managerProto[name] + }; + }); + managerProto.open = managerProto.connect = function () { + debug('MockedManager.prototype.open or connect ... arguments:', arguments); + setTimeout(function () { + pub(server.subscribers, 'connect'); + pub(server.events, 'connection'); + }, 0); + }; + managerProto.socket = function () { + debug('MockedManager.prototype.socket ...'); + var socket = new MockedSocket(server); + socket.connected = true; + socket.disconnected = false; + return socket; + }; + return origs; + } + function restoreManager(managerProto, origs) { + debug('Restore.'); + origs.forEach(function (orig) { + managerProto[orig.name] = orig.method; + }); + } + function resetManagerCache(cache) { + for (var i in cache) { + if (cache.hasOwnProperty(i)) { + delete cache[i]; + } + } + } + var _DEBUG = false; + function debug(msg, obj) { + if (_DEBUG) { + console.log.apply(console, arguments); + } + } + module.exports = { + Server: MockedServer, + mockSocketManager: mockManager, + restoreManager: restoreManager + }; +}); +/*can-fixture-socket@2.0.0#can-fixture-socket*/ +define('can-fixture-socket@2.0.0#can-fixture-socket', [ + 'require', + 'exports', + 'module', + './src/index', + './src/store' +], function (require, exports, module) { + var fixtureSocket = require('./src/index'); + var fixtureStore = require('./src/store'); + module.exports = { + Server: fixtureSocket.Server, + requestHandlerToListener: fixtureStore.requestHandlerToListener, + storeToListeners: fixtureStore.storeToListeners + }; +}); +/*parseuri@0.0.5#index*/ +define('parseuri@0.0.5#index', function (require, exports, module) { + var re = /^(?:(?![^:@]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/; + var parts = [ + 'source', + 'protocol', + 'authority', + 'userInfo', + 'user', + 'password', + 'host', + 'port', + 'relative', + 'path', + 'directory', + 'file', + 'query', + 'anchor' + ]; + module.exports = function parseuri(str) { + var src = str, b = str.indexOf('['), e = str.indexOf(']'); + if (b != -1 && e != -1) { + str = str.substring(0, b) + str.substring(b, e).replace(/:/g, ';') + str.substring(e, str.length); + } + var m = re.exec(str || ''), uri = {}, i = 14; + while (i--) { + uri[parts[i]] = m[i] || ''; + } + if (b != -1 && e != -1) { + uri.source = src; + uri.host = uri.host.substring(1, uri.host.length - 1).replace(/;/g, ':'); + uri.authority = uri.authority.replace('[', '').replace(']', '').replace(/;/g, ':'); + uri.ipv6uri = true; + } + return uri; + }; +}); +/*ms@0.7.2#index*/ +define('ms@0.7.2#index', function (require, exports, module) { + var s = 1000; + var m = s * 60; + var h = m * 60; + var d = h * 24; + var y = d * 365.25; + module.exports = function (val, options) { + options = options || {}; + var type = typeof val; + if (type === 'string' && val.length > 0) { + return parse(val); + } else if (type === 'number' && isNaN(val) === false) { + return options.long ? fmtLong(val) : fmtShort(val); + } + throw new Error('val is not a non-empty string or a valid number. val=' + JSON.stringify(val)); + }; + function parse(str) { + str = String(str); + if (str.length > 10000) { + return; + } + var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str); + if (!match) { + return; + } + var n = parseFloat(match[1]); + var type = (match[2] || 'ms').toLowerCase(); + switch (type) { + case 'years': + case 'year': + case 'yrs': + case 'yr': + case 'y': + return n * y; + case 'days': + case 'day': + case 'd': + return n * d; + case 'hours': + case 'hour': + case 'hrs': + case 'hr': + case 'h': + return n * h; + case 'minutes': + case 'minute': + case 'mins': + case 'min': + case 'm': + return n * m; + case 'seconds': + case 'second': + case 'secs': + case 'sec': + case 's': + return n * s; + case 'milliseconds': + case 'millisecond': + case 'msecs': + case 'msec': + case 'ms': + return n; + default: + return undefined; + } + } + function fmtShort(ms) { + if (ms >= d) { + return Math.round(ms / d) + 'd'; + } + if (ms >= h) { + return Math.round(ms / h) + 'h'; + } + if (ms >= m) { + return Math.round(ms / m) + 'm'; + } + if (ms >= s) { + return Math.round(ms / s) + 's'; + } + return ms + 'ms'; + } + function fmtLong(ms) { + return plural(ms, d, 'day') || plural(ms, h, 'hour') || plural(ms, m, 'minute') || plural(ms, s, 'second') || ms + ' ms'; + } + function plural(ms, n, name) { + if (ms < n) { + return; + } + if (ms < n * 1.5) { + return Math.floor(ms / n) + ' ' + name; + } + return Math.ceil(ms / n) + ' ' + name + 's'; + } +}); +/*debug@2.3.3#debug*/ +define('debug@2.3.3#debug', [ + 'require', + 'exports', + 'module', + 'ms' +], function (require, exports, module) { + exports = module.exports = debug.debug = debug; + exports.coerce = coerce; + exports.disable = disable; + exports.enable = enable; + exports.enabled = enabled; + exports.humanize = require('ms'); + exports.names = []; + exports.skips = []; + exports.formatters = {}; + var prevColor = 0; + var prevTime; + function selectColor() { + return exports.colors[prevColor++ % exports.colors.length]; + } + function debug(namespace) { + function disabled() { + } + disabled.enabled = false; + function enabled() { + var self = enabled; + var curr = +new Date(); + var ms = curr - (prevTime || curr); + self.diff = ms; + self.prev = prevTime; + self.curr = curr; + prevTime = curr; + if (null == self.useColors) + self.useColors = exports.useColors(); + if (null == self.color && self.useColors) + self.color = selectColor(); + var args = new Array(arguments.length); + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i]; + } + args[0] = exports.coerce(args[0]); + if ('string' !== typeof args[0]) { + args = ['%o'].concat(args); + } + var index = 0; + args[0] = args[0].replace(/%([a-z%])/g, function (match, format) { + if (match === '%%') + return match; + index++; + var formatter = exports.formatters[format]; + if ('function' === typeof formatter) { + var val = args[index]; + match = formatter.call(self, val); + args.splice(index, 1); + index--; + } + return match; + }); + args = exports.formatArgs.apply(self, args); + var logFn = enabled.log || exports.log || console.log.bind(console); + logFn.apply(self, args); + } + enabled.enabled = true; + var fn = exports.enabled(namespace) ? enabled : disabled; + fn.namespace = namespace; + return fn; + } + function enable(namespaces) { + exports.save(namespaces); + var split = (namespaces || '').split(/[\s,]+/); + var len = split.length; + for (var i = 0; i < len; i++) { + if (!split[i]) + continue; + namespaces = split[i].replace(/[\\^$+?.()|[\]{}]/g, '\\$&').replace(/\*/g, '.*?'); + if (namespaces[0] === '-') { + exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); + } else { + exports.names.push(new RegExp('^' + namespaces + '$')); + } + } + } + function disable() { + exports.enable(''); + } + function enabled(name) { + var i, len; + for (i = 0, len = exports.skips.length; i < len; i++) { + if (exports.skips[i].test(name)) { + return false; + } + } + for (i = 0, len = exports.names.length; i < len; i++) { + if (exports.names[i].test(name)) { + return true; + } + } + return false; + } + function coerce(val) { + if (val instanceof Error) + return val.stack || val.message; + return val; + } +}); +/*debug@2.3.3#browser*/ +define('debug@2.3.3#browser', [ + 'require', + 'exports', + 'module', + './debug' +], function (require, exports, module) { + exports = module.exports = require('./debug'); + exports.log = log; + exports.formatArgs = formatArgs; + exports.save = save; + exports.load = load; + exports.useColors = useColors; + exports.storage = 'undefined' != typeof chrome && 'undefined' != typeof chrome.storage ? chrome.storage.local : localstorage(); + exports.colors = [ + 'lightseagreen', + 'forestgreen', + 'goldenrod', + 'dodgerblue', + 'darkorchid', + 'crimson' + ]; + function useColors() { + return typeof document !== 'undefined' && 'WebkitAppearance' in document.documentElement.style || window.console && (console.firebug || console.exception && console.table) || navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31; + } + exports.formatters.j = function (v) { + try { + return JSON.stringify(v); + } catch (err) { + return '[UnexpectedJSONParseError]: ' + err.message; + } + }; + function formatArgs() { + var args = arguments; + var useColors = this.useColors; + args[0] = (useColors ? '%c' : '') + this.namespace + (useColors ? ' %c' : ' ') + args[0] + (useColors ? '%c ' : ' ') + '+' + exports.humanize(this.diff); + if (!useColors) + return args; + var c = 'color: ' + this.color; + args = [ + args[0], + c, + 'color: inherit' + ].concat(Array.prototype.slice.call(args, 1)); + var index = 0; + var lastC = 0; + args[0].replace(/%[a-z%]/g, function (match) { + if ('%%' === match) + return; + index++; + if ('%c' === match) { + lastC = index; + } + }); + args.splice(lastC, 0, c); + return args; + } + function log() { + return 'object' === typeof console && console.log && Function.prototype.apply.call(console.log, console, arguments); + } + function save(namespaces) { + try { + if (null == namespaces) { + exports.storage.removeItem('debug'); + } else { + exports.storage.debug = namespaces; + } + } catch (e) { + } + } + function load() { + var r; + try { + return exports.storage.debug; + } catch (e) { + } + if (typeof process !== 'undefined' && 'env' in process) { + return process.env.DEBUG; + } + } + exports.enable(load()); + function localstorage() { + try { + return window.localStorage; + } catch (e) { + } + } +}); +/*socket.io-client@1.7.4#lib/url*/ +define('socket.io-client@1.7.4#lib/url', [ + 'require', + 'exports', + 'module', + 'parseuri', + 'debug' +], function (require, exports, module) { + (function (global, require, exports, module) { + var parseuri = require('parseuri'); + var debug = require('debug')('socket.io-client:url'); + module.exports = url; + function url(uri, loc) { + var obj = uri; + loc = loc || global.location; + if (null == uri) + uri = loc.protocol + '//' + loc.host; + if ('string' === typeof uri) { + if ('/' === uri.charAt(0)) { + if ('/' === uri.charAt(1)) { + uri = loc.protocol + uri; + } else { + uri = loc.host + uri; + } + } + if (!/^(https?|wss?):\/\//.test(uri)) { + debug('protocol-less url %s', uri); + if ('undefined' !== typeof loc) { + uri = loc.protocol + '//' + uri; + } else { + uri = 'https://' + uri; + } + } + debug('parse %s', uri); + obj = parseuri(uri); + } + if (!obj.port) { + if (/^(http|ws)$/.test(obj.protocol)) { + obj.port = '80'; + } else if (/^(http|ws)s$/.test(obj.protocol)) { + obj.port = '443'; + } + } + obj.path = obj.path || '/'; + var ipv6 = obj.host.indexOf(':') !== -1; + var host = ipv6 ? '[' + obj.host + ']' : obj.host; + obj.id = obj.protocol + '://' + host + ':' + obj.port; + obj.href = obj.protocol + '://' + host + (loc && loc.port === obj.port ? '' : ':' + obj.port); + return obj; + } + }(function () { + return this; + }(), require, exports, module)); +}); +/*ms@0.7.1#index*/ +define('ms@0.7.1#index', function (require, exports, module) { + var s = 1000; + var m = s * 60; + var h = m * 60; + var d = h * 24; + var y = d * 365.25; + module.exports = function (val, options) { + options = options || {}; + if ('string' == typeof val) + return parse(val); + return options.long ? long(val) : short(val); + }; + function parse(str) { + str = '' + str; + if (str.length > 10000) + return; + var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str); + if (!match) + return; + var n = parseFloat(match[1]); + var type = (match[2] || 'ms').toLowerCase(); + switch (type) { + case 'years': + case 'year': + case 'yrs': + case 'yr': + case 'y': + return n * y; + case 'days': + case 'day': + case 'd': + return n * d; + case 'hours': + case 'hour': + case 'hrs': + case 'hr': + case 'h': + return n * h; + case 'minutes': + case 'minute': + case 'mins': + case 'min': + case 'm': + return n * m; + case 'seconds': + case 'second': + case 'secs': + case 'sec': + case 's': + return n * s; + case 'milliseconds': + case 'millisecond': + case 'msecs': + case 'msec': + case 'ms': + return n; + } + } + function short(ms) { + if (ms >= d) + return Math.round(ms / d) + 'd'; + if (ms >= h) + return Math.round(ms / h) + 'h'; + if (ms >= m) + return Math.round(ms / m) + 'm'; + if (ms >= s) + return Math.round(ms / s) + 's'; + return ms + 'ms'; + } + function long(ms) { + return plural(ms, d, 'day') || plural(ms, h, 'hour') || plural(ms, m, 'minute') || plural(ms, s, 'second') || ms + ' ms'; + } + function plural(ms, n, name) { + if (ms < n) + return; + if (ms < n * 1.5) + return Math.floor(ms / n) + ' ' + name; + return Math.ceil(ms / n) + ' ' + name + 's'; + } +}); +/*debug@2.2.0#debug*/ +define('debug@2.2.0#debug', [ + 'require', + 'exports', + 'module', + 'ms' +], function (require, exports, module) { + exports = module.exports = debug; + exports.coerce = coerce; + exports.disable = disable; + exports.enable = enable; + exports.enabled = enabled; + exports.humanize = require('ms'); + exports.names = []; + exports.skips = []; + exports.formatters = {}; + var prevColor = 0; + var prevTime; + function selectColor() { + return exports.colors[prevColor++ % exports.colors.length]; + } + function debug(namespace) { + function disabled() { + } + disabled.enabled = false; + function enabled() { + var self = enabled; + var curr = +new Date(); + var ms = curr - (prevTime || curr); + self.diff = ms; + self.prev = prevTime; + self.curr = curr; + prevTime = curr; + if (null == self.useColors) + self.useColors = exports.useColors(); + if (null == self.color && self.useColors) + self.color = selectColor(); + var args = Array.prototype.slice.call(arguments); + args[0] = exports.coerce(args[0]); + if ('string' !== typeof args[0]) { + args = ['%o'].concat(args); + } + var index = 0; + args[0] = args[0].replace(/%([a-z%])/g, function (match, format) { + if (match === '%%') + return match; + index++; + var formatter = exports.formatters[format]; + if ('function' === typeof formatter) { + var val = args[index]; + match = formatter.call(self, val); + args.splice(index, 1); + index--; + } + return match; + }); + if ('function' === typeof exports.formatArgs) { + args = exports.formatArgs.apply(self, args); + } + var logFn = enabled.log || exports.log || console.log.bind(console); + logFn.apply(self, args); + } + enabled.enabled = true; + var fn = exports.enabled(namespace) ? enabled : disabled; + fn.namespace = namespace; + return fn; + } + function enable(namespaces) { + exports.save(namespaces); + var split = (namespaces || '').split(/[\s,]+/); + var len = split.length; + for (var i = 0; i < len; i++) { + if (!split[i]) + continue; + namespaces = split[i].replace(/\*/g, '.*?'); + if (namespaces[0] === '-') { + exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); + } else { + exports.names.push(new RegExp('^' + namespaces + '$')); + } + } + } + function disable() { + exports.enable(''); + } + function enabled(name) { + var i, len; + for (i = 0, len = exports.skips.length; i < len; i++) { + if (exports.skips[i].test(name)) { + return false; + } + } + for (i = 0, len = exports.names.length; i < len; i++) { + if (exports.names[i].test(name)) { + return true; + } + } + return false; + } + function coerce(val) { + if (val instanceof Error) + return val.stack || val.message; + return val; + } +}); +/*debug@2.2.0#browser*/ +define('debug@2.2.0#browser', [ + 'require', + 'exports', + 'module', + './debug' +], function (require, exports, module) { + exports = module.exports = require('./debug'); + exports.log = log; + exports.formatArgs = formatArgs; + exports.save = save; + exports.load = load; + exports.useColors = useColors; + exports.storage = 'undefined' != typeof chrome && 'undefined' != typeof chrome.storage ? chrome.storage.local : localstorage(); + exports.colors = [ + 'lightseagreen', + 'forestgreen', + 'goldenrod', + 'dodgerblue', + 'darkorchid', + 'crimson' + ]; + function useColors() { + return 'WebkitAppearance' in document.documentElement.style || window.console && (console.firebug || console.exception && console.table) || navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31; + } + exports.formatters.j = function (v) { + return JSON.stringify(v); + }; + function formatArgs() { + var args = arguments; + var useColors = this.useColors; + args[0] = (useColors ? '%c' : '') + this.namespace + (useColors ? ' %c' : ' ') + args[0] + (useColors ? '%c ' : ' ') + '+' + exports.humanize(this.diff); + if (!useColors) + return args; + var c = 'color: ' + this.color; + args = [ + args[0], + c, + 'color: inherit' + ].concat(Array.prototype.slice.call(args, 1)); + var index = 0; + var lastC = 0; + args[0].replace(/%[a-z%]/g, function (match) { + if ('%%' === match) + return; + index++; + if ('%c' === match) { + lastC = index; + } + }); + args.splice(lastC, 0, c); + return args; + } + function log() { + return 'object' === typeof console && console.log && Function.prototype.apply.call(console.log, console, arguments); + } + function save(namespaces) { + try { + if (null == namespaces) { + exports.storage.removeItem('debug'); + } else { + exports.storage.debug = namespaces; + } + } catch (e) { + } + } + function load() { + var r; + try { + r = exports.storage.debug; + } catch (e) { + } + return r; + } + exports.enable(load()); + function localstorage() { + try { + return window.localStorage; + } catch (e) { + } + } +}); +/*json3@3.3.2#lib/json3*/ +; +(function () { + var isLoader = typeof define === 'function' && define.amd; + var objectTypes = { + 'function': true, + 'object': true + }; + var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; + var root = objectTypes[typeof window] && window || this, freeGlobal = freeExports && objectTypes[typeof module] && module && !module.nodeType && typeof global == 'object' && global; + if (freeGlobal && (freeGlobal['global'] === freeGlobal || freeGlobal['window'] === freeGlobal || freeGlobal['self'] === freeGlobal)) { + root = freeGlobal; + } + function runInContext(context, exports) { + context || (context = root['Object']()); + exports || (exports = root['Object']()); + var Number = context['Number'] || root['Number'], String = context['String'] || root['String'], Object = context['Object'] || root['Object'], Date = context['Date'] || root['Date'], SyntaxError = context['SyntaxError'] || root['SyntaxError'], TypeError = context['TypeError'] || root['TypeError'], Math = context['Math'] || root['Math'], nativeJSON = context['JSON'] || root['JSON']; + if (typeof nativeJSON == 'object' && nativeJSON) { + exports.stringify = nativeJSON.stringify; + exports.parse = nativeJSON.parse; + } + var objectProto = Object.prototype, getClass = objectProto.toString, isProperty, forEach, undef; + var isExtended = new Date(-3509827334573292); + try { + isExtended = isExtended.getUTCFullYear() == -109252 && isExtended.getUTCMonth() === 0 && isExtended.getUTCDate() === 1 && isExtended.getUTCHours() == 10 && isExtended.getUTCMinutes() == 37 && isExtended.getUTCSeconds() == 6 && isExtended.getUTCMilliseconds() == 708; + } catch (exception) { + } + function has(name) { + if (has[name] !== undef) { + return has[name]; + } + var isSupported; + if (name == 'bug-string-char-index') { + isSupported = 'a'[0] != 'a'; + } else if (name == 'json') { + isSupported = has('json-stringify') && has('json-parse'); + } else { + var value, serialized = '{"a":[1,true,false,null,"\\u0000\\b\\n\\f\\r\\t"]}'; + if (name == 'json-stringify') { + var stringify = exports.stringify, stringifySupported = typeof stringify == 'function' && isExtended; + if (stringifySupported) { + (value = function () { + return 1; + }).toJSON = value; + try { + stringifySupported = stringify(0) === '0' && stringify(new Number()) === '0' && stringify(new String()) == '""' && stringify(getClass) === undef && stringify(undef) === undef && stringify() === undef && stringify(value) === '1' && stringify([value]) == '[1]' && stringify([undef]) == '[null]' && stringify(null) == 'null' && stringify([ + undef, + getClass, + null + ]) == '[null,null,null]' && stringify({ + 'a': [ + value, + true, + false, + null, + '\0\b\n\f\r\t' + ] + }) == serialized && stringify(null, value) === '1' && stringify([ + 1, + 2 + ], null, 1) == '[\n 1,\n 2\n]' && stringify(new Date(-8640000000000000)) == '"-271821-04-20T00:00:00.000Z"' && stringify(new Date(8640000000000000)) == '"+275760-09-13T00:00:00.000Z"' && stringify(new Date(-62198755200000)) == '"-000001-01-01T00:00:00.000Z"' && stringify(new Date(-1)) == '"1969-12-31T23:59:59.999Z"'; + } catch (exception) { + stringifySupported = false; + } + } + isSupported = stringifySupported; + } + if (name == 'json-parse') { + var parse = exports.parse; + if (typeof parse == 'function') { + try { + if (parse('0') === 0 && !parse(false)) { + value = parse(serialized); + var parseSupported = value['a'].length == 5 && value['a'][0] === 1; + if (parseSupported) { + try { + parseSupported = !parse('"\t"'); + } catch (exception) { + } + if (parseSupported) { + try { + parseSupported = parse('01') !== 1; + } catch (exception) { + } + } + if (parseSupported) { + try { + parseSupported = parse('1.') !== 1; + } catch (exception) { + } + } + } + } + } catch (exception) { + parseSupported = false; + } + } + isSupported = parseSupported; + } + } + return has[name] = !!isSupported; + } + if (!has('json')) { + var functionClass = '[object Function]', dateClass = '[object Date]', numberClass = '[object Number]', stringClass = '[object String]', arrayClass = '[object Array]', booleanClass = '[object Boolean]'; + var charIndexBuggy = has('bug-string-char-index'); + if (!isExtended) { + var floor = Math.floor; + var Months = [ + 0, + 31, + 59, + 90, + 120, + 151, + 181, + 212, + 243, + 273, + 304, + 334 + ]; + var getDay = function (year, month) { + return Months[month] + 365 * (year - 1970) + floor((year - 1969 + (month = +(month > 1))) / 4) - floor((year - 1901 + month) / 100) + floor((year - 1601 + month) / 400); + }; + } + if (!(isProperty = objectProto.hasOwnProperty)) { + isProperty = function (property) { + var members = {}, constructor; + if ((members.__proto__ = null, members.__proto__ = { 'toString': 1 }, members).toString != getClass) { + isProperty = function (property) { + var original = this.__proto__, result = property in (this.__proto__ = null, this); + this.__proto__ = original; + return result; + }; + } else { + constructor = members.constructor; + isProperty = function (property) { + var parent = (this.constructor || constructor).prototype; + return property in this && !(property in parent && this[property] === parent[property]); + }; + } + members = null; + return isProperty.call(this, property); + }; + } + forEach = function (object, callback) { + var size = 0, Properties, members, property; + (Properties = function () { + this.valueOf = 0; + }).prototype.valueOf = 0; + members = new Properties(); + for (property in members) { + if (isProperty.call(members, property)) { + size++; + } + } + Properties = members = null; + if (!size) { + members = [ + 'valueOf', + 'toString', + 'toLocaleString', + 'propertyIsEnumerable', + 'isPrototypeOf', + 'hasOwnProperty', + 'constructor' + ]; + forEach = function (object, callback) { + var isFunction = getClass.call(object) == functionClass, property, length; + var hasProperty = !isFunction && typeof object.constructor != 'function' && objectTypes[typeof object.hasOwnProperty] && object.hasOwnProperty || isProperty; + for (property in object) { + if (!(isFunction && property == 'prototype') && hasProperty.call(object, property)) { + callback(property); + } + } + for (length = members.length; property = members[--length]; hasProperty.call(object, property) && callback(property)); + }; + } else if (size == 2) { + forEach = function (object, callback) { + var members = {}, isFunction = getClass.call(object) == functionClass, property; + for (property in object) { + if (!(isFunction && property == 'prototype') && !isProperty.call(members, property) && (members[property] = 1) && isProperty.call(object, property)) { + callback(property); + } + } + }; + } else { + forEach = function (object, callback) { + var isFunction = getClass.call(object) == functionClass, property, isConstructor; + for (property in object) { + if (!(isFunction && property == 'prototype') && isProperty.call(object, property) && !(isConstructor = property === 'constructor')) { + callback(property); + } + } + if (isConstructor || isProperty.call(object, property = 'constructor')) { + callback(property); + } + }; + } + return forEach(object, callback); + }; + if (!has('json-stringify')) { + var Escapes = { + 92: '\\\\', + 34: '\\"', + 8: '\\b', + 12: '\\f', + 10: '\\n', + 13: '\\r', + 9: '\\t' + }; + var leadingZeroes = '000000'; + var toPaddedString = function (width, value) { + return (leadingZeroes + (value || 0)).slice(-width); + }; + var unicodePrefix = '\\u00'; + var quote = function (value) { + var result = '"', index = 0, length = value.length, useCharIndex = !charIndexBuggy || length > 10; + var symbols = useCharIndex && (charIndexBuggy ? value.split('') : value); + for (; index < length; index++) { + var charCode = value.charCodeAt(index); + switch (charCode) { + case 8: + case 9: + case 10: + case 12: + case 13: + case 34: + case 92: + result += Escapes[charCode]; + break; + default: + if (charCode < 32) { + result += unicodePrefix + toPaddedString(2, charCode.toString(16)); + break; + } + result += useCharIndex ? symbols[index] : value.charAt(index); + } + } + return result + '"'; + }; + var serialize = function (property, object, callback, properties, whitespace, indentation, stack) { + var value, className, year, month, date, time, hours, minutes, seconds, milliseconds, results, element, index, length, prefix, result; + try { + value = object[property]; + } catch (exception) { + } + if (typeof value == 'object' && value) { + className = getClass.call(value); + if (className == dateClass && !isProperty.call(value, 'toJSON')) { + if (value > -1 / 0 && value < 1 / 0) { + if (getDay) { + date = floor(value / 86400000); + for (year = floor(date / 365.2425) + 1970 - 1; getDay(year + 1, 0) <= date; year++); + for (month = floor((date - getDay(year, 0)) / 30.42); getDay(year, month + 1) <= date; month++); + date = 1 + date - getDay(year, month); + time = (value % 86400000 + 86400000) % 86400000; + hours = floor(time / 3600000) % 24; + minutes = floor(time / 60000) % 60; + seconds = floor(time / 1000) % 60; + milliseconds = time % 1000; + } else { + year = value.getUTCFullYear(); + month = value.getUTCMonth(); + date = value.getUTCDate(); + hours = value.getUTCHours(); + minutes = value.getUTCMinutes(); + seconds = value.getUTCSeconds(); + milliseconds = value.getUTCMilliseconds(); + } + value = (year <= 0 || year >= 10000 ? (year < 0 ? '-' : '+') + toPaddedString(6, year < 0 ? -year : year) : toPaddedString(4, year)) + '-' + toPaddedString(2, month + 1) + '-' + toPaddedString(2, date) + 'T' + toPaddedString(2, hours) + ':' + toPaddedString(2, minutes) + ':' + toPaddedString(2, seconds) + '.' + toPaddedString(3, milliseconds) + 'Z'; + } else { + value = null; + } + } else if (typeof value.toJSON == 'function' && (className != numberClass && className != stringClass && className != arrayClass || isProperty.call(value, 'toJSON'))) { + value = value.toJSON(property); + } + } + if (callback) { + value = callback.call(object, property, value); + } + if (value === null) { + return 'null'; + } + className = getClass.call(value); + if (className == booleanClass) { + return '' + value; + } else if (className == numberClass) { + return value > -1 / 0 && value < 1 / 0 ? '' + value : 'null'; + } else if (className == stringClass) { + return quote('' + value); + } + if (typeof value == 'object') { + for (length = stack.length; length--;) { + if (stack[length] === value) { + throw TypeError(); + } + } + stack.push(value); + results = []; + prefix = indentation; + indentation += whitespace; + if (className == arrayClass) { + for (index = 0, length = value.length; index < length; index++) { + element = serialize(index, value, callback, properties, whitespace, indentation, stack); + results.push(element === undef ? 'null' : element); + } + result = results.length ? whitespace ? '[\n' + indentation + results.join(',\n' + indentation) + '\n' + prefix + ']' : '[' + results.join(',') + ']' : '[]'; + } else { + forEach(properties || value, function (property) { + var element = serialize(property, value, callback, properties, whitespace, indentation, stack); + if (element !== undef) { + results.push(quote(property) + ':' + (whitespace ? ' ' : '') + element); + } + }); + result = results.length ? whitespace ? '{\n' + indentation + results.join(',\n' + indentation) + '\n' + prefix + '}' : '{' + results.join(',') + '}' : '{}'; + } + stack.pop(); + return result; + } + }; + exports.stringify = function (source, filter, width) { + var whitespace, callback, properties, className; + if (objectTypes[typeof filter] && filter) { + if ((className = getClass.call(filter)) == functionClass) { + callback = filter; + } else if (className == arrayClass) { + properties = {}; + for (var index = 0, length = filter.length, value; index < length; value = filter[index++], (className = getClass.call(value), className == stringClass || className == numberClass) && (properties[value] = 1)); + } + } + if (width) { + if ((className = getClass.call(width)) == numberClass) { + if ((width -= width % 1) > 0) { + for (whitespace = '', width > 10 && (width = 10); whitespace.length < width; whitespace += ' '); + } + } else if (className == stringClass) { + whitespace = width.length <= 10 ? width : width.slice(0, 10); + } + } + return serialize('', (value = {}, value[''] = source, value), callback, properties, whitespace, '', []); + }; + } + if (!has('json-parse')) { + var fromCharCode = String.fromCharCode; + var Unescapes = { + 92: '\\', + 34: '"', + 47: '/', + 98: '\b', + 116: '\t', + 110: '\n', + 102: '\f', + 114: '\r' + }; + var Index, Source; + var abort = function () { + Index = Source = null; + throw SyntaxError(); + }; + var lex = function () { + var source = Source, length = source.length, value, begin, position, isSigned, charCode; + while (Index < length) { + charCode = source.charCodeAt(Index); + switch (charCode) { + case 9: + case 10: + case 13: + case 32: + Index++; + break; + case 123: + case 125: + case 91: + case 93: + case 58: + case 44: + value = charIndexBuggy ? source.charAt(Index) : source[Index]; + Index++; + return value; + case 34: + for (value = '@', Index++; Index < length;) { + charCode = source.charCodeAt(Index); + if (charCode < 32) { + abort(); + } else if (charCode == 92) { + charCode = source.charCodeAt(++Index); + switch (charCode) { + case 92: + case 34: + case 47: + case 98: + case 116: + case 110: + case 102: + case 114: + value += Unescapes[charCode]; + Index++; + break; + case 117: + begin = ++Index; + for (position = Index + 4; Index < position; Index++) { + charCode = source.charCodeAt(Index); + if (!(charCode >= 48 && charCode <= 57 || charCode >= 97 && charCode <= 102 || charCode >= 65 && charCode <= 70)) { + abort(); + } + } + value += fromCharCode('0x' + source.slice(begin, Index)); + break; + default: + abort(); + } + } else { + if (charCode == 34) { + break; + } + charCode = source.charCodeAt(Index); + begin = Index; + while (charCode >= 32 && charCode != 92 && charCode != 34) { + charCode = source.charCodeAt(++Index); + } + value += source.slice(begin, Index); + } + } + if (source.charCodeAt(Index) == 34) { + Index++; + return value; + } + abort(); + default: + begin = Index; + if (charCode == 45) { + isSigned = true; + charCode = source.charCodeAt(++Index); + } + if (charCode >= 48 && charCode <= 57) { + if (charCode == 48 && (charCode = source.charCodeAt(Index + 1), charCode >= 48 && charCode <= 57)) { + abort(); + } + isSigned = false; + for (; Index < length && (charCode = source.charCodeAt(Index), charCode >= 48 && charCode <= 57); Index++); + if (source.charCodeAt(Index) == 46) { + position = ++Index; + for (; position < length && (charCode = source.charCodeAt(position), charCode >= 48 && charCode <= 57); position++); + if (position == Index) { + abort(); + } + Index = position; + } + charCode = source.charCodeAt(Index); + if (charCode == 101 || charCode == 69) { + charCode = source.charCodeAt(++Index); + if (charCode == 43 || charCode == 45) { + Index++; + } + for (position = Index; position < length && (charCode = source.charCodeAt(position), charCode >= 48 && charCode <= 57); position++); + if (position == Index) { + abort(); + } + Index = position; + } + return +source.slice(begin, Index); + } + if (isSigned) { + abort(); + } + if (source.slice(Index, Index + 4) == 'true') { + Index += 4; + return true; + } else if (source.slice(Index, Index + 5) == 'false') { + Index += 5; + return false; + } else if (source.slice(Index, Index + 4) == 'null') { + Index += 4; + return null; + } + abort(); + } + } + return '$'; + }; + var get = function (value) { + var results, hasMembers; + if (value == '$') { + abort(); + } + if (typeof value == 'string') { + if ((charIndexBuggy ? value.charAt(0) : value[0]) == '@') { + return value.slice(1); + } + if (value == '[') { + results = []; + for (;; hasMembers || (hasMembers = true)) { + value = lex(); + if (value == ']') { + break; + } + if (hasMembers) { + if (value == ',') { + value = lex(); + if (value == ']') { + abort(); + } + } else { + abort(); + } + } + if (value == ',') { + abort(); + } + results.push(get(value)); + } + return results; + } else if (value == '{') { + results = {}; + for (;; hasMembers || (hasMembers = true)) { + value = lex(); + if (value == '}') { + break; + } + if (hasMembers) { + if (value == ',') { + value = lex(); + if (value == '}') { + abort(); + } + } else { + abort(); + } + } + if (value == ',' || typeof value != 'string' || (charIndexBuggy ? value.charAt(0) : value[0]) != '@' || lex() != ':') { + abort(); + } + results[value.slice(1)] = get(lex()); + } + return results; + } + abort(); + } + return value; + }; + var update = function (source, property, callback) { + var element = walk(source, property, callback); + if (element === undef) { + delete source[property]; + } else { + source[property] = element; + } + }; + var walk = function (source, property, callback) { + var value = source[property], length; + if (typeof value == 'object' && value) { + if (getClass.call(value) == arrayClass) { + for (length = value.length; length--;) { + update(value, length, callback); + } + } else { + forEach(value, function (property) { + update(value, property, callback); + }); + } + } + return callback.call(source, property, value); + }; + exports.parse = function (source, callback) { + var result, value; + Index = 0; + Source = '' + source; + result = get(lex()); + if (lex() != '$') { + abort(); + } + Index = Source = null; + return callback && getClass.call(callback) == functionClass ? walk((value = {}, value[''] = result, value), '', callback) : result; + }; + } + } + exports['runInContext'] = runInContext; + return exports; + } + if (freeExports && !isLoader) { + runInContext(root, freeExports); + } else { + var nativeJSON = root.JSON, previousJSON = root['JSON3'], isRestored = false; + var JSON3 = runInContext(root, root['JSON3'] = { + 'noConflict': function () { + if (!isRestored) { + isRestored = true; + root.JSON = nativeJSON; + root['JSON3'] = previousJSON; + nativeJSON = previousJSON = null; + } + return JSON3; + } + }); + root.JSON = { + 'parse': JSON3.parse, + 'stringify': JSON3.stringify + }; + } + if (isLoader) { + define('json3@3.3.2#lib/json3', function () { + return JSON3; + }); + } +}.call(this)); +/*component-emitter@1.1.2#index*/ +define('component-emitter@1.1.2#index', function (require, exports, module) { + module.exports = Emitter; + function Emitter(obj) { + if (obj) + return mixin(obj); + } + ; + function mixin(obj) { + for (var key in Emitter.prototype) { + obj[key] = Emitter.prototype[key]; + } + return obj; + } + Emitter.prototype.on = Emitter.prototype.addEventListener = function (event, fn) { + this._callbacks = this._callbacks || {}; + (this._callbacks[event] = this._callbacks[event] || []).push(fn); + return this; + }; + Emitter.prototype.once = function (event, fn) { + var self = this; + this._callbacks = this._callbacks || {}; + function on() { + self.off(event, on); + fn.apply(this, arguments); + } + on.fn = fn; + this.on(event, on); + return this; + }; + Emitter.prototype.off = Emitter.prototype.removeListener = Emitter.prototype.removeAllListeners = Emitter.prototype.removeEventListener = function (event, fn) { + this._callbacks = this._callbacks || {}; + if (0 == arguments.length) { + this._callbacks = {}; + return this; + } + var callbacks = this._callbacks[event]; + if (!callbacks) + return this; + if (1 == arguments.length) { + delete this._callbacks[event]; + return this; + } + var cb; + for (var i = 0; i < callbacks.length; i++) { + cb = callbacks[i]; + if (cb === fn || cb.fn === fn) { + callbacks.splice(i, 1); + break; + } + } + return this; + }; + Emitter.prototype.emit = function (event) { + this._callbacks = this._callbacks || {}; + var args = [].slice.call(arguments, 1), callbacks = this._callbacks[event]; + if (callbacks) { + callbacks = callbacks.slice(0); + for (var i = 0, len = callbacks.length; i < len; ++i) { + callbacks[i].apply(this, args); + } + } + return this; + }; + Emitter.prototype.listeners = function (event) { + this._callbacks = this._callbacks || {}; + return this._callbacks[event] || []; + }; + Emitter.prototype.hasListeners = function (event) { + return !!this.listeners(event).length; + }; +}); +/*isarray@0.0.1#index*/ +define('isarray@0.0.1#index', function (require, exports, module) { + module.exports = Array.isArray || function (arr) { + return Object.prototype.toString.call(arr) == '[object Array]'; + }; +}); +/*socket.io-parser@2.3.1#is-buffer*/ +define('socket.io-parser@2.3.1#is-buffer', function (require, exports, module) { + (function (global, require, exports, module) { + module.exports = isBuf; + function isBuf(obj) { + return global.Buffer && global.Buffer.isBuffer(obj) || global.ArrayBuffer && obj instanceof ArrayBuffer; + } + }(function () { + return this; + }(), require, exports, module)); +}); +/*socket.io-parser@2.3.1#binary*/ +define('socket.io-parser@2.3.1#binary', [ + 'require', + 'exports', + 'module', + 'isarray', + './is-buffer' +], function (require, exports, module) { + (function (global, require, exports, module) { + var isArray = require('isarray'); + var isBuf = require('./is-buffer'); + exports.deconstructPacket = function (packet) { + var buffers = []; + var packetData = packet.data; + function _deconstructPacket(data) { + if (!data) + return data; + if (isBuf(data)) { + var placeholder = { + _placeholder: true, + num: buffers.length + }; + buffers.push(data); + return placeholder; + } else if (isArray(data)) { + var newData = new Array(data.length); + for (var i = 0; i < data.length; i++) { + newData[i] = _deconstructPacket(data[i]); + } + return newData; + } else if ('object' == typeof data && !(data instanceof Date)) { + var newData = {}; + for (var key in data) { + newData[key] = _deconstructPacket(data[key]); + } + return newData; + } + return data; + } + var pack = packet; + pack.data = _deconstructPacket(packetData); + pack.attachments = buffers.length; + return { + packet: pack, + buffers: buffers + }; + }; + exports.reconstructPacket = function (packet, buffers) { + var curPlaceHolder = 0; + function _reconstructPacket(data) { + if (data && data._placeholder) { + var buf = buffers[data.num]; + return buf; + } else if (isArray(data)) { + for (var i = 0; i < data.length; i++) { + data[i] = _reconstructPacket(data[i]); + } + return data; + } else if (data && 'object' == typeof data) { + for (var key in data) { + data[key] = _reconstructPacket(data[key]); + } + return data; + } + return data; + } + packet.data = _reconstructPacket(packet.data); + packet.attachments = undefined; + return packet; + }; + exports.removeBlobs = function (data, callback) { + function _removeBlobs(obj, curKey, containingObject) { + if (!obj) + return obj; + if (global.Blob && obj instanceof Blob || global.File && obj instanceof File) { + pendingBlobs++; + var fileReader = new FileReader(); + fileReader.onload = function () { + if (containingObject) { + containingObject[curKey] = this.result; + } else { + bloblessData = this.result; + } + if (!--pendingBlobs) { + callback(bloblessData); + } + }; + fileReader.readAsArrayBuffer(obj); + } else if (isArray(obj)) { + for (var i = 0; i < obj.length; i++) { + _removeBlobs(obj[i], i, obj); + } + } else if (obj && 'object' == typeof obj && !isBuf(obj)) { + for (var key in obj) { + _removeBlobs(obj[key], key, obj); + } + } + } + var pendingBlobs = 0; + var bloblessData = data; + _removeBlobs(bloblessData); + if (!pendingBlobs) { + callback(bloblessData); + } + }; + }(function () { + return this; + }(), require, exports, module)); +}); +/*socket.io-parser@2.3.1#index*/ +define('socket.io-parser@2.3.1#index', [ + 'require', + 'exports', + 'module', + 'debug', + 'json3', + 'component-emitter', + './binary', + './is-buffer' +], function (require, exports, module) { + var debug = require('debug')('socket.io-parser'); + var json = require('json3'); + var Emitter = require('component-emitter'); + var binary = require('./binary'); + var isBuf = require('./is-buffer'); + exports.protocol = 4; + exports.types = [ + 'CONNECT', + 'DISCONNECT', + 'EVENT', + 'ACK', + 'ERROR', + 'BINARY_EVENT', + 'BINARY_ACK' + ]; + exports.CONNECT = 0; + exports.DISCONNECT = 1; + exports.EVENT = 2; + exports.ACK = 3; + exports.ERROR = 4; + exports.BINARY_EVENT = 5; + exports.BINARY_ACK = 6; + exports.Encoder = Encoder; + exports.Decoder = Decoder; + function Encoder() { + } + Encoder.prototype.encode = function (obj, callback) { + debug('encoding packet %j', obj); + if (exports.BINARY_EVENT == obj.type || exports.BINARY_ACK == obj.type) { + encodeAsBinary(obj, callback); + } else { + var encoding = encodeAsString(obj); + callback([encoding]); + } + }; + function encodeAsString(obj) { + var str = ''; + var nsp = false; + str += obj.type; + if (exports.BINARY_EVENT == obj.type || exports.BINARY_ACK == obj.type) { + str += obj.attachments; + str += '-'; + } + if (obj.nsp && '/' != obj.nsp) { + nsp = true; + str += obj.nsp; + } + if (null != obj.id) { + if (nsp) { + str += ','; + nsp = false; + } + str += obj.id; + } + if (null != obj.data) { + if (nsp) + str += ','; + str += json.stringify(obj.data); + } + debug('encoded %j as %s', obj, str); + return str; + } + function encodeAsBinary(obj, callback) { + function writeEncoding(bloblessData) { + var deconstruction = binary.deconstructPacket(bloblessData); + var pack = encodeAsString(deconstruction.packet); + var buffers = deconstruction.buffers; + buffers.unshift(pack); + callback(buffers); + } + binary.removeBlobs(obj, writeEncoding); + } + function Decoder() { + this.reconstructor = null; + } + Emitter(Decoder.prototype); + Decoder.prototype.add = function (obj) { + var packet; + if ('string' == typeof obj) { + packet = decodeString(obj); + if (exports.BINARY_EVENT == packet.type || exports.BINARY_ACK == packet.type) { + this.reconstructor = new BinaryReconstructor(packet); + if (this.reconstructor.reconPack.attachments === 0) { + this.emit('decoded', packet); + } + } else { + this.emit('decoded', packet); + } + } else if (isBuf(obj) || obj.base64) { + if (!this.reconstructor) { + throw new Error('got binary data when not reconstructing a packet'); + } else { + packet = this.reconstructor.takeBinaryData(obj); + if (packet) { + this.reconstructor = null; + this.emit('decoded', packet); + } + } + } else { + throw new Error('Unknown type: ' + obj); + } + }; + function decodeString(str) { + var p = {}; + var i = 0; + p.type = Number(str.charAt(0)); + if (null == exports.types[p.type]) + return error(); + if (exports.BINARY_EVENT == p.type || exports.BINARY_ACK == p.type) { + var buf = ''; + while (str.charAt(++i) != '-') { + buf += str.charAt(i); + if (i == str.length) + break; + } + if (buf != Number(buf) || str.charAt(i) != '-') { + throw new Error('Illegal attachments'); + } + p.attachments = Number(buf); + } + if ('/' == str.charAt(i + 1)) { + p.nsp = ''; + while (++i) { + var c = str.charAt(i); + if (',' == c) + break; + p.nsp += c; + if (i == str.length) + break; + } + } else { + p.nsp = '/'; + } + var next = str.charAt(i + 1); + if ('' !== next && Number(next) == next) { + p.id = ''; + while (++i) { + var c = str.charAt(i); + if (null == c || Number(c) != c) { + --i; + break; + } + p.id += str.charAt(i); + if (i == str.length) + break; + } + p.id = Number(p.id); + } + if (str.charAt(++i)) { + p = tryParse(p, str.substr(i)); + } + debug('decoded %s as %j', str, p); + return p; + } + function tryParse(p, str) { + try { + p.data = json.parse(str); + } catch (e) { + return error(); + } + return p; + } + ; + Decoder.prototype.destroy = function () { + if (this.reconstructor) { + this.reconstructor.finishedReconstruction(); + } + }; + function BinaryReconstructor(packet) { + this.reconPack = packet; + this.buffers = []; + } + BinaryReconstructor.prototype.takeBinaryData = function (binData) { + this.buffers.push(binData); + if (this.buffers.length == this.reconPack.attachments) { + var packet = binary.reconstructPacket(this.reconPack, this.buffers); + this.finishedReconstruction(); + return packet; + } + return null; + }; + BinaryReconstructor.prototype.finishedReconstruction = function () { + this.reconPack = null; + this.buffers = []; + }; + function error(data) { + return { + type: exports.ERROR, + data: 'parser error' + }; + } +}); +/*has-cors@1.1.0#index*/ +define('has-cors@1.1.0#index', function (require, exports, module) { + try { + module.exports = typeof XMLHttpRequest !== 'undefined' && 'withCredentials' in new XMLHttpRequest(); + } catch (err) { + module.exports = false; + } +}); +/*engine.io-client@1.8.5#lib/xmlhttprequest*/ +define('engine.io-client@1.8.5#lib/xmlhttprequest', [ + 'require', + 'exports', + 'module', + 'has-cors' +], function (require, exports, module) { + (function (global, require, exports, module) { + var hasCORS = require('has-cors'); + module.exports = function (opts) { + var xdomain = opts.xdomain; + var xscheme = opts.xscheme; + var enablesXDR = opts.enablesXDR; + try { + if ('undefined' !== typeof XMLHttpRequest && (!xdomain || hasCORS)) { + return new XMLHttpRequest(); + } + } catch (e) { + } + try { + if ('undefined' !== typeof XDomainRequest && !xscheme && enablesXDR) { + return new XDomainRequest(); + } + } catch (e) { + } + if (!xdomain) { + try { + return new global[(['Active'].concat('Object').join('X'))]('Microsoft.XMLHTTP'); + } catch (e) { + } + } + }; + }(function () { + return this; + }(), require, exports, module)); +}); +/*engine.io-parser@1.3.2#lib/keys*/ +define('engine.io-parser@1.3.2#lib/keys', function (require, exports, module) { + module.exports = Object.keys || function keys(obj) { + var arr = []; + var has = Object.prototype.hasOwnProperty; + for (var i in obj) { + if (has.call(obj, i)) { + arr.push(i); + } + } + return arr; + }; +}); +/*has-binary@0.1.7#index*/ +define('has-binary@0.1.7#index', [ + 'require', + 'exports', + 'module', + 'isarray' +], function (require, exports, module) { + (function (global, require, exports, module) { + var isArray = require('isarray'); + module.exports = hasBinary; + function hasBinary(data) { + function _hasBinary(obj) { + if (!obj) + return false; + if (global.Buffer && global.Buffer.isBuffer && global.Buffer.isBuffer(obj) || global.ArrayBuffer && obj instanceof ArrayBuffer || global.Blob && obj instanceof Blob || global.File && obj instanceof File) { + return true; + } + if (isArray(obj)) { + for (var i = 0; i < obj.length; i++) { + if (_hasBinary(obj[i])) { + return true; + } + } + } else if (obj && 'object' == typeof obj) { + if (obj.toJSON && 'function' == typeof obj.toJSON) { + obj = obj.toJSON(); + } + for (var key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key) && _hasBinary(obj[key])) { + return true; + } + } + } + return false; + } + return _hasBinary(data); + } + }(function () { + return this; + }(), require, exports, module)); +}); +/*arraybuffer.slice@0.0.6#index*/ +define('arraybuffer.slice@0.0.6#index', function (require, exports, module) { + module.exports = function (arraybuffer, start, end) { + var bytes = arraybuffer.byteLength; + start = start || 0; + end = end || bytes; + if (arraybuffer.slice) { + return arraybuffer.slice(start, end); + } + if (start < 0) { + start += bytes; + } + if (end < 0) { + end += bytes; + } + if (end > bytes) { + end = bytes; + } + if (start >= bytes || start >= end || bytes === 0) { + return new ArrayBuffer(0); + } + var abv = new Uint8Array(arraybuffer); + var result = new Uint8Array(end - start); + for (var i = start, ii = 0; i < end; i++, ii++) { + result[ii] = abv[i]; + } + return result.buffer; + }; +}); +/*after@0.8.2#index*/ +define('after@0.8.2#index', function (require, exports, module) { + module.exports = after; + function after(count, callback, err_cb) { + var bail = false; + err_cb = err_cb || noop; + proxy.count = count; + return count === 0 ? callback() : proxy; + function proxy(err, result) { + if (proxy.count <= 0) { + throw new Error('after called too many times'); + } + --proxy.count; + if (err) { + bail = true; + callback(err); + callback = err_cb; + } else if (proxy.count === 0 && !bail) { + callback(null, result); + } + } + } + function noop() { + } +}); +/*wtf-8@1.0.0#wtf-8*/ +; +(function (root) { + var freeExports = typeof exports == 'object' && exports; + var freeModule = typeof module == 'object' && module && module.exports == freeExports && module; + var freeGlobal = typeof global == 'object' && global; + if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) { + root = freeGlobal; + } + var stringFromCharCode = String.fromCharCode; + function ucs2decode(string) { + var output = []; + var counter = 0; + var length = string.length; + var value; + var extra; + while (counter < length) { + value = string.charCodeAt(counter++); + if (value >= 55296 && value <= 56319 && counter < length) { + extra = string.charCodeAt(counter++); + if ((extra & 64512) == 56320) { + output.push(((value & 1023) << 10) + (extra & 1023) + 65536); + } else { + output.push(value); + counter--; + } + } else { + output.push(value); + } + } + return output; + } + function ucs2encode(array) { + var length = array.length; + var index = -1; + var value; + var output = ''; + while (++index < length) { + value = array[index]; + if (value > 65535) { + value -= 65536; + output += stringFromCharCode(value >>> 10 & 1023 | 55296); + value = 56320 | value & 1023; + } + output += stringFromCharCode(value); + } + return output; + } + function createByte(codePoint, shift) { + return stringFromCharCode(codePoint >> shift & 63 | 128); + } + function encodeCodePoint(codePoint) { + if ((codePoint & 4294967168) == 0) { + return stringFromCharCode(codePoint); + } + var symbol = ''; + if ((codePoint & 4294965248) == 0) { + symbol = stringFromCharCode(codePoint >> 6 & 31 | 192); + } else if ((codePoint & 4294901760) == 0) { + symbol = stringFromCharCode(codePoint >> 12 & 15 | 224); + symbol += createByte(codePoint, 6); + } else if ((codePoint & 4292870144) == 0) { + symbol = stringFromCharCode(codePoint >> 18 & 7 | 240); + symbol += createByte(codePoint, 12); + symbol += createByte(codePoint, 6); + } + symbol += stringFromCharCode(codePoint & 63 | 128); + return symbol; + } + function wtf8encode(string) { + var codePoints = ucs2decode(string); + var length = codePoints.length; + var index = -1; + var codePoint; + var byteString = ''; + while (++index < length) { + codePoint = codePoints[index]; + byteString += encodeCodePoint(codePoint); + } + return byteString; + } + function readContinuationByte() { + if (byteIndex >= byteCount) { + throw Error('Invalid byte index'); + } + var continuationByte = byteArray[byteIndex] & 255; + byteIndex++; + if ((continuationByte & 192) == 128) { + return continuationByte & 63; + } + throw Error('Invalid continuation byte'); + } + function decodeSymbol() { + var byte1; + var byte2; + var byte3; + var byte4; + var codePoint; + if (byteIndex > byteCount) { + throw Error('Invalid byte index'); + } + if (byteIndex == byteCount) { + return false; + } + byte1 = byteArray[byteIndex] & 255; + byteIndex++; + if ((byte1 & 128) == 0) { + return byte1; + } + if ((byte1 & 224) == 192) { + var byte2 = readContinuationByte(); + codePoint = (byte1 & 31) << 6 | byte2; + if (codePoint >= 128) { + return codePoint; + } else { + throw Error('Invalid continuation byte'); + } + } + if ((byte1 & 240) == 224) { + byte2 = readContinuationByte(); + byte3 = readContinuationByte(); + codePoint = (byte1 & 15) << 12 | byte2 << 6 | byte3; + if (codePoint >= 2048) { + return codePoint; + } else { + throw Error('Invalid continuation byte'); + } + } + if ((byte1 & 248) == 240) { + byte2 = readContinuationByte(); + byte3 = readContinuationByte(); + byte4 = readContinuationByte(); + codePoint = (byte1 & 15) << 18 | byte2 << 12 | byte3 << 6 | byte4; + if (codePoint >= 65536 && codePoint <= 1114111) { + return codePoint; + } + } + throw Error('Invalid WTF-8 detected'); + } + var byteArray; + var byteCount; + var byteIndex; + function wtf8decode(byteString) { + byteArray = ucs2decode(byteString); + byteCount = byteArray.length; + byteIndex = 0; + var codePoints = []; + var tmp; + while ((tmp = decodeSymbol()) !== false) { + codePoints.push(tmp); + } + return ucs2encode(codePoints); + } + var wtf8 = { + 'version': '1.0.0', + 'encode': wtf8encode, + 'decode': wtf8decode + }; + if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { + define('wtf-8@1.0.0#wtf-8', function () { + return wtf8; + }); + } else if (freeExports && !freeExports.nodeType) { + if (freeModule) { + freeModule.exports = wtf8; + } else { + var object = {}; + var hasOwnProperty = object.hasOwnProperty; + for (var key in wtf8) { + hasOwnProperty.call(wtf8, key) && (freeExports[key] = wtf8[key]); + } + } + } else { + root.wtf8 = wtf8; + } +}(this)); +/*base64-arraybuffer@0.1.5#lib/base64-arraybuffer*/ +define('base64-arraybuffer@0.1.5#lib/base64-arraybuffer', function (require, exports, module) { + (function () { + 'use strict'; + var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + var lookup = new Uint8Array(256); + for (var i = 0; i < chars.length; i++) { + lookup[chars.charCodeAt(i)] = i; + } + exports.encode = function (arraybuffer) { + var bytes = new Uint8Array(arraybuffer), i, len = bytes.length, base64 = ''; + for (i = 0; i < len; i += 3) { + base64 += chars[bytes[i] >> 2]; + base64 += chars[(bytes[i] & 3) << 4 | bytes[i + 1] >> 4]; + base64 += chars[(bytes[i + 1] & 15) << 2 | bytes[i + 2] >> 6]; + base64 += chars[bytes[i + 2] & 63]; + } + if (len % 3 === 2) { + base64 = base64.substring(0, base64.length - 1) + '='; + } else if (len % 3 === 1) { + base64 = base64.substring(0, base64.length - 2) + '=='; + } + return base64; + }; + exports.decode = function (base64) { + var bufferLength = base64.length * 0.75, len = base64.length, i, p = 0, encoded1, encoded2, encoded3, encoded4; + if (base64[base64.length - 1] === '=') { + bufferLength--; + if (base64[base64.length - 2] === '=') { + bufferLength--; + } + } + var arraybuffer = new ArrayBuffer(bufferLength), bytes = new Uint8Array(arraybuffer); + for (i = 0; i < len; i += 4) { + encoded1 = lookup[base64.charCodeAt(i)]; + encoded2 = lookup[base64.charCodeAt(i + 1)]; + encoded3 = lookup[base64.charCodeAt(i + 2)]; + encoded4 = lookup[base64.charCodeAt(i + 3)]; + bytes[p++] = encoded1 << 2 | encoded2 >> 4; + bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2; + bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63; + } + return arraybuffer; + }; + }()); +}); +/*blob@0.0.4#index*/ +define('blob@0.0.4#index', function (require, exports, module) { + (function (global, require, exports, module) { + var BlobBuilder = global.BlobBuilder || global.WebKitBlobBuilder || global.MSBlobBuilder || global.MozBlobBuilder; + var blobSupported = function () { + try { + var a = new Blob(['hi']); + return a.size === 2; + } catch (e) { + return false; + } + }(); + var blobSupportsArrayBufferView = blobSupported && function () { + try { + var b = new Blob([new Uint8Array([ + 1, + 2 + ])]); + return b.size === 2; + } catch (e) { + return false; + } + }(); + var blobBuilderSupported = BlobBuilder && BlobBuilder.prototype.append && BlobBuilder.prototype.getBlob; + function mapArrayBufferViews(ary) { + for (var i = 0; i < ary.length; i++) { + var chunk = ary[i]; + if (chunk.buffer instanceof ArrayBuffer) { + var buf = chunk.buffer; + if (chunk.byteLength !== buf.byteLength) { + var copy = new Uint8Array(chunk.byteLength); + copy.set(new Uint8Array(buf, chunk.byteOffset, chunk.byteLength)); + buf = copy.buffer; + } + ary[i] = buf; + } + } + } + function BlobBuilderConstructor(ary, options) { + options = options || {}; + var bb = new BlobBuilder(); + mapArrayBufferViews(ary); + for (var i = 0; i < ary.length; i++) { + bb.append(ary[i]); + } + return options.type ? bb.getBlob(options.type) : bb.getBlob(); + } + ; + function BlobConstructor(ary, options) { + mapArrayBufferViews(ary); + return new Blob(ary, options || {}); + } + ; + module.exports = function () { + if (blobSupported) { + return blobSupportsArrayBufferView ? global.Blob : BlobConstructor; + } else if (blobBuilderSupported) { + return BlobBuilderConstructor; + } else { + return undefined; + } + }(); + }(function () { + return this; + }(), require, exports, module)); +}); +/*engine.io-parser@1.3.2#lib/browser*/ +define('engine.io-parser@1.3.2#lib/browser', [ + 'require', + 'exports', + 'module', + './keys', + 'has-binary', + 'arraybuffer.slice', + 'after', + 'wtf-8', + 'base64-arraybuffer', + 'blob' +], function (require, exports, module) { + (function (global, require, exports, module) { + var keys = require('./keys'); + var hasBinary = require('has-binary'); + var sliceBuffer = require('arraybuffer.slice'); + var after = require('after'); + var utf8 = require('wtf-8'); + var base64encoder; + if (global && global.ArrayBuffer) { + base64encoder = require('base64-arraybuffer'); + } + var isAndroid = typeof navigator !== 'undefined' && /Android/i.test(navigator.userAgent); + var isPhantomJS = typeof navigator !== 'undefined' && /PhantomJS/i.test(navigator.userAgent); + var dontSendBlobs = isAndroid || isPhantomJS; + exports.protocol = 3; + var packets = exports.packets = { + open: 0, + close: 1, + ping: 2, + pong: 3, + message: 4, + upgrade: 5, + noop: 6 + }; + var packetslist = keys(packets); + var err = { + type: 'error', + data: 'parser error' + }; + var Blob = require('blob'); + exports.encodePacket = function (packet, supportsBinary, utf8encode, callback) { + if ('function' == typeof supportsBinary) { + callback = supportsBinary; + supportsBinary = false; + } + if ('function' == typeof utf8encode) { + callback = utf8encode; + utf8encode = null; + } + var data = packet.data === undefined ? undefined : packet.data.buffer || packet.data; + if (global.ArrayBuffer && data instanceof ArrayBuffer) { + return encodeArrayBuffer(packet, supportsBinary, callback); + } else if (Blob && data instanceof global.Blob) { + return encodeBlob(packet, supportsBinary, callback); + } + if (data && data.base64) { + return encodeBase64Object(packet, callback); + } + var encoded = packets[packet.type]; + if (undefined !== packet.data) { + encoded += utf8encode ? utf8.encode(String(packet.data)) : String(packet.data); + } + return callback('' + encoded); + }; + function encodeBase64Object(packet, callback) { + var message = 'b' + exports.packets[packet.type] + packet.data.data; + return callback(message); + } + function encodeArrayBuffer(packet, supportsBinary, callback) { + if (!supportsBinary) { + return exports.encodeBase64Packet(packet, callback); + } + var data = packet.data; + var contentArray = new Uint8Array(data); + var resultBuffer = new Uint8Array(1 + data.byteLength); + resultBuffer[0] = packets[packet.type]; + for (var i = 0; i < contentArray.length; i++) { + resultBuffer[i + 1] = contentArray[i]; + } + return callback(resultBuffer.buffer); + } + function encodeBlobAsArrayBuffer(packet, supportsBinary, callback) { + if (!supportsBinary) { + return exports.encodeBase64Packet(packet, callback); + } + var fr = new FileReader(); + fr.onload = function () { + packet.data = fr.result; + exports.encodePacket(packet, supportsBinary, true, callback); + }; + return fr.readAsArrayBuffer(packet.data); + } + function encodeBlob(packet, supportsBinary, callback) { + if (!supportsBinary) { + return exports.encodeBase64Packet(packet, callback); + } + if (dontSendBlobs) { + return encodeBlobAsArrayBuffer(packet, supportsBinary, callback); + } + var length = new Uint8Array(1); + length[0] = packets[packet.type]; + var blob = new Blob([ + length.buffer, + packet.data + ]); + return callback(blob); + } + exports.encodeBase64Packet = function (packet, callback) { + var message = 'b' + exports.packets[packet.type]; + if (Blob && packet.data instanceof global.Blob) { + var fr = new FileReader(); + fr.onload = function () { + var b64 = fr.result.split(',')[1]; + callback(message + b64); + }; + return fr.readAsDataURL(packet.data); + } + var b64data; + try { + b64data = String.fromCharCode.apply(null, new Uint8Array(packet.data)); + } catch (e) { + var typed = new Uint8Array(packet.data); + var basic = new Array(typed.length); + for (var i = 0; i < typed.length; i++) { + basic[i] = typed[i]; + } + b64data = String.fromCharCode.apply(null, basic); + } + message += global.btoa(b64data); + return callback(message); + }; + exports.decodePacket = function (data, binaryType, utf8decode) { + if (data === undefined) { + return err; + } + if (typeof data == 'string') { + if (data.charAt(0) == 'b') { + return exports.decodeBase64Packet(data.substr(1), binaryType); + } + if (utf8decode) { + data = tryDecode(data); + if (data === false) { + return err; + } + } + var type = data.charAt(0); + if (Number(type) != type || !packetslist[type]) { + return err; + } + if (data.length > 1) { + return { + type: packetslist[type], + data: data.substring(1) + }; + } else { + return { type: packetslist[type] }; + } + } + var asArray = new Uint8Array(data); + var type = asArray[0]; + var rest = sliceBuffer(data, 1); + if (Blob && binaryType === 'blob') { + rest = new Blob([rest]); + } + return { + type: packetslist[type], + data: rest + }; + }; + function tryDecode(data) { + try { + data = utf8.decode(data); + } catch (e) { + return false; + } + return data; + } + exports.decodeBase64Packet = function (msg, binaryType) { + var type = packetslist[msg.charAt(0)]; + if (!base64encoder) { + return { + type: type, + data: { + base64: true, + data: msg.substr(1) + } + }; + } + var data = base64encoder.decode(msg.substr(1)); + if (binaryType === 'blob' && Blob) { + data = new Blob([data]); + } + return { + type: type, + data: data + }; + }; + exports.encodePayload = function (packets, supportsBinary, callback) { + if (typeof supportsBinary == 'function') { + callback = supportsBinary; + supportsBinary = null; + } + var isBinary = hasBinary(packets); + if (supportsBinary && isBinary) { + if (Blob && !dontSendBlobs) { + return exports.encodePayloadAsBlob(packets, callback); + } + return exports.encodePayloadAsArrayBuffer(packets, callback); + } + if (!packets.length) { + return callback('0:'); + } + function setLengthHeader(message) { + return message.length + ':' + message; + } + function encodeOne(packet, doneCallback) { + exports.encodePacket(packet, !isBinary ? false : supportsBinary, true, function (message) { + doneCallback(null, setLengthHeader(message)); + }); + } + map(packets, encodeOne, function (err, results) { + return callback(results.join('')); + }); + }; + function map(ary, each, done) { + var result = new Array(ary.length); + var next = after(ary.length, done); + var eachWithIndex = function (i, el, cb) { + each(el, function (error, msg) { + result[i] = msg; + cb(error, result); + }); + }; + for (var i = 0; i < ary.length; i++) { + eachWithIndex(i, ary[i], next); + } + } + exports.decodePayload = function (data, binaryType, callback) { + if (typeof data != 'string') { + return exports.decodePayloadAsBinary(data, binaryType, callback); + } + if (typeof binaryType === 'function') { + callback = binaryType; + binaryType = null; + } + var packet; + if (data == '') { + return callback(err, 0, 1); + } + var length = '', n, msg; + for (var i = 0, l = data.length; i < l; i++) { + var chr = data.charAt(i); + if (':' != chr) { + length += chr; + } else { + if ('' == length || length != (n = Number(length))) { + return callback(err, 0, 1); + } + msg = data.substr(i + 1, n); + if (length != msg.length) { + return callback(err, 0, 1); + } + if (msg.length) { + packet = exports.decodePacket(msg, binaryType, true); + if (err.type == packet.type && err.data == packet.data) { + return callback(err, 0, 1); + } + var ret = callback(packet, i + n, l); + if (false === ret) + return; + } + i += n; + length = ''; + } + } + if (length != '') { + return callback(err, 0, 1); + } + }; + exports.encodePayloadAsArrayBuffer = function (packets, callback) { + if (!packets.length) { + return callback(new ArrayBuffer(0)); + } + function encodeOne(packet, doneCallback) { + exports.encodePacket(packet, true, true, function (data) { + return doneCallback(null, data); + }); + } + map(packets, encodeOne, function (err, encodedPackets) { + var totalLength = encodedPackets.reduce(function (acc, p) { + var len; + if (typeof p === 'string') { + len = p.length; + } else { + len = p.byteLength; + } + return acc + len.toString().length + len + 2; + }, 0); + var resultArray = new Uint8Array(totalLength); + var bufferIndex = 0; + encodedPackets.forEach(function (p) { + var isString = typeof p === 'string'; + var ab = p; + if (isString) { + var view = new Uint8Array(p.length); + for (var i = 0; i < p.length; i++) { + view[i] = p.charCodeAt(i); + } + ab = view.buffer; + } + if (isString) { + resultArray[bufferIndex++] = 0; + } else { + resultArray[bufferIndex++] = 1; + } + var lenStr = ab.byteLength.toString(); + for (var i = 0; i < lenStr.length; i++) { + resultArray[bufferIndex++] = parseInt(lenStr[i]); + } + resultArray[bufferIndex++] = 255; + var view = new Uint8Array(ab); + for (var i = 0; i < view.length; i++) { + resultArray[bufferIndex++] = view[i]; + } + }); + return callback(resultArray.buffer); + }); + }; + exports.encodePayloadAsBlob = function (packets, callback) { + function encodeOne(packet, doneCallback) { + exports.encodePacket(packet, true, true, function (encoded) { + var binaryIdentifier = new Uint8Array(1); + binaryIdentifier[0] = 1; + if (typeof encoded === 'string') { + var view = new Uint8Array(encoded.length); + for (var i = 0; i < encoded.length; i++) { + view[i] = encoded.charCodeAt(i); + } + encoded = view.buffer; + binaryIdentifier[0] = 0; + } + var len = encoded instanceof ArrayBuffer ? encoded.byteLength : encoded.size; + var lenStr = len.toString(); + var lengthAry = new Uint8Array(lenStr.length + 1); + for (var i = 0; i < lenStr.length; i++) { + lengthAry[i] = parseInt(lenStr[i]); + } + lengthAry[lenStr.length] = 255; + if (Blob) { + var blob = new Blob([ + binaryIdentifier.buffer, + lengthAry.buffer, + encoded + ]); + doneCallback(null, blob); + } + }); + } + map(packets, encodeOne, function (err, results) { + return callback(new Blob(results)); + }); + }; + exports.decodePayloadAsBinary = function (data, binaryType, callback) { + if (typeof binaryType === 'function') { + callback = binaryType; + binaryType = null; + } + var bufferTail = data; + var buffers = []; + var numberTooLong = false; + while (bufferTail.byteLength > 0) { + var tailArray = new Uint8Array(bufferTail); + var isString = tailArray[0] === 0; + var msgLength = ''; + for (var i = 1;; i++) { + if (tailArray[i] == 255) + break; + if (msgLength.length > 310) { + numberTooLong = true; + break; + } + msgLength += tailArray[i]; + } + if (numberTooLong) + return callback(err, 0, 1); + bufferTail = sliceBuffer(bufferTail, 2 + msgLength.length); + msgLength = parseInt(msgLength); + var msg = sliceBuffer(bufferTail, 0, msgLength); + if (isString) { + try { + msg = String.fromCharCode.apply(null, new Uint8Array(msg)); + } catch (e) { + var typed = new Uint8Array(msg); + msg = ''; + for (var i = 0; i < typed.length; i++) { + msg += String.fromCharCode(typed[i]); + } + } + } + buffers.push(msg); + bufferTail = sliceBuffer(bufferTail, msgLength); + } + var total = buffers.length; + buffers.forEach(function (buffer, i) { + callback(exports.decodePacket(buffer, binaryType, true), i, total); + }); + }; + }(function () { + return this; + }(), require, exports, module)); +}); +/*component-emitter@1.2.1#index*/ +define('component-emitter@1.2.1#index', function (require, exports, module) { + if (typeof module !== 'undefined') { + module.exports = Emitter; + } + function Emitter(obj) { + if (obj) + return mixin(obj); + } + ; + function mixin(obj) { + for (var key in Emitter.prototype) { + obj[key] = Emitter.prototype[key]; + } + return obj; + } + Emitter.prototype.on = Emitter.prototype.addEventListener = function (event, fn) { + this._callbacks = this._callbacks || {}; + (this._callbacks['$' + event] = this._callbacks['$' + event] || []).push(fn); + return this; + }; + Emitter.prototype.once = function (event, fn) { + function on() { + this.off(event, on); + fn.apply(this, arguments); + } + on.fn = fn; + this.on(event, on); + return this; + }; + Emitter.prototype.off = Emitter.prototype.removeListener = Emitter.prototype.removeAllListeners = Emitter.prototype.removeEventListener = function (event, fn) { + this._callbacks = this._callbacks || {}; + if (0 == arguments.length) { + this._callbacks = {}; + return this; + } + var callbacks = this._callbacks['$' + event]; + if (!callbacks) + return this; + if (1 == arguments.length) { + delete this._callbacks['$' + event]; + return this; + } + var cb; + for (var i = 0; i < callbacks.length; i++) { + cb = callbacks[i]; + if (cb === fn || cb.fn === fn) { + callbacks.splice(i, 1); + break; + } + } + return this; + }; + Emitter.prototype.emit = function (event) { + this._callbacks = this._callbacks || {}; + var args = [].slice.call(arguments, 1), callbacks = this._callbacks['$' + event]; + if (callbacks) { + callbacks = callbacks.slice(0); + for (var i = 0, len = callbacks.length; i < len; ++i) { + callbacks[i].apply(this, args); + } + } + return this; + }; + Emitter.prototype.listeners = function (event) { + this._callbacks = this._callbacks || {}; + return this._callbacks['$' + event] || []; + }; + Emitter.prototype.hasListeners = function (event) { + return !!this.listeners(event).length; + }; +}); +/*engine.io-client@1.8.5#lib/transport*/ +define('engine.io-client@1.8.5#lib/transport', [ + 'require', + 'exports', + 'module', + 'engine.io-parser', + 'component-emitter' +], function (require, exports, module) { + var parser = require('engine.io-parser'); + var Emitter = require('component-emitter'); + module.exports = Transport; + function Transport(opts) { + this.path = opts.path; + this.hostname = opts.hostname; + this.port = opts.port; + this.secure = opts.secure; + this.query = opts.query; + this.timestampParam = opts.timestampParam; + this.timestampRequests = opts.timestampRequests; + this.readyState = ''; + this.agent = opts.agent || false; + this.socket = opts.socket; + this.enablesXDR = opts.enablesXDR; + this.pfx = opts.pfx; + this.key = opts.key; + this.passphrase = opts.passphrase; + this.cert = opts.cert; + this.ca = opts.ca; + this.ciphers = opts.ciphers; + this.rejectUnauthorized = opts.rejectUnauthorized; + this.forceNode = opts.forceNode; + this.extraHeaders = opts.extraHeaders; + this.localAddress = opts.localAddress; + } + Emitter(Transport.prototype); + Transport.prototype.onError = function (msg, desc) { + var err = new Error(msg); + err.type = 'TransportError'; + err.description = desc; + this.emit('error', err); + return this; + }; + Transport.prototype.open = function () { + if ('closed' === this.readyState || '' === this.readyState) { + this.readyState = 'opening'; + this.doOpen(); + } + return this; + }; + Transport.prototype.close = function () { + if ('opening' === this.readyState || 'open' === this.readyState) { + this.doClose(); + this.onClose(); + } + return this; + }; + Transport.prototype.send = function (packets) { + if ('open' === this.readyState) { + this.write(packets); + } else { + throw new Error('Transport not open'); + } + }; + Transport.prototype.onOpen = function () { + this.readyState = 'open'; + this.writable = true; + this.emit('open'); + }; + Transport.prototype.onData = function (data) { + var packet = parser.decodePacket(data, this.socket.binaryType); + this.onPacket(packet); + }; + Transport.prototype.onPacket = function (packet) { + this.emit('packet', packet); + }; + Transport.prototype.onClose = function () { + this.readyState = 'closed'; + this.emit('close'); + }; +}); +/*parseqs@0.0.5#index*/ +define('parseqs@0.0.5#index', function (require, exports, module) { + exports.encode = function (obj) { + var str = ''; + for (var i in obj) { + if (obj.hasOwnProperty(i)) { + if (str.length) + str += '&'; + str += encodeURIComponent(i) + '=' + encodeURIComponent(obj[i]); + } + } + return str; + }; + exports.decode = function (qs) { + var qry = {}; + var pairs = qs.split('&'); + for (var i = 0, l = pairs.length; i < l; i++) { + var pair = pairs[i].split('='); + qry[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]); + } + return qry; + }; +}); +/*component-inherit@0.0.3#index*/ +define('component-inherit@0.0.3#index', function (require, exports, module) { + module.exports = function (a, b) { + var fn = function () { + }; + fn.prototype = b.prototype; + a.prototype = new fn(); + a.prototype.constructor = a; + }; +}); +/*yeast@0.1.2#index*/ +define('yeast@0.1.2#index', function (require, exports, module) { + 'use strict'; + var alphabet = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_'.split(''), length = 64, map = {}, seed = 0, i = 0, prev; + function encode(num) { + var encoded = ''; + do { + encoded = alphabet[num % length] + encoded; + num = Math.floor(num / length); + } while (num > 0); + return encoded; + } + function decode(str) { + var decoded = 0; + for (i = 0; i < str.length; i++) { + decoded = decoded * length + map[str.charAt(i)]; + } + return decoded; + } + function yeast() { + var now = encode(+new Date()); + if (now !== prev) + return seed = 0, prev = now; + return now + '.' + encode(seed++); + } + for (; i < length; i++) + map[alphabet[i]] = i; + yeast.encode = encode; + yeast.decode = decode; + module.exports = yeast; +}); +/*engine.io-client@1.8.5#lib/transports/polling*/ +define('engine.io-client@1.8.5#lib/transports/polling', [ + 'require', + 'exports', + 'module', + '../transport', + 'parseqs', + 'engine.io-parser', + 'component-inherit', + 'yeast', + 'debug', + 'xmlhttprequest-ssl' +], function (require, exports, module) { + var Transport = require('../transport'); + var parseqs = require('parseqs'); + var parser = require('engine.io-parser'); + var inherit = require('component-inherit'); + var yeast = require('yeast'); + var debug = require('debug')('engine.io-client:polling'); + module.exports = Polling; + var hasXHR2 = function () { + var XMLHttpRequest = require('xmlhttprequest-ssl'); + var xhr = new XMLHttpRequest({ xdomain: false }); + return null != xhr.responseType; + }(); + function Polling(opts) { + var forceBase64 = opts && opts.forceBase64; + if (!hasXHR2 || forceBase64) { + this.supportsBinary = false; + } + Transport.call(this, opts); + } + inherit(Polling, Transport); + Polling.prototype.name = 'polling'; + Polling.prototype.doOpen = function () { + this.poll(); + }; + Polling.prototype.pause = function (onPause) { + var self = this; + this.readyState = 'pausing'; + function pause() { + debug('paused'); + self.readyState = 'paused'; + onPause(); + } + if (this.polling || !this.writable) { + var total = 0; + if (this.polling) { + debug('we are currently polling - waiting to pause'); + total++; + this.once('pollComplete', function () { + debug('pre-pause polling complete'); + --total || pause(); + }); + } + if (!this.writable) { + debug('we are currently writing - waiting to pause'); + total++; + this.once('drain', function () { + debug('pre-pause writing complete'); + --total || pause(); + }); + } + } else { + pause(); + } + }; + Polling.prototype.poll = function () { + debug('polling'); + this.polling = true; + this.doPoll(); + this.emit('poll'); + }; + Polling.prototype.onData = function (data) { + var self = this; + debug('polling got data %s', data); + var callback = function (packet, index, total) { + if ('opening' === self.readyState) { + self.onOpen(); + } + if ('close' === packet.type) { + self.onClose(); + return false; + } + self.onPacket(packet); + }; + parser.decodePayload(data, this.socket.binaryType, callback); + if ('closed' !== this.readyState) { + this.polling = false; + this.emit('pollComplete'); + if ('open' === this.readyState) { + this.poll(); + } else { + debug('ignoring poll - transport state "%s"', this.readyState); + } + } + }; + Polling.prototype.doClose = function () { + var self = this; + function close() { + debug('writing close packet'); + self.write([{ type: 'close' }]); + } + if ('open' === this.readyState) { + debug('transport open - closing'); + close(); + } else { + debug('transport not open - deferring close'); + this.once('open', close); + } + }; + Polling.prototype.write = function (packets) { + var self = this; + this.writable = false; + var callbackfn = function () { + self.writable = true; + self.emit('drain'); + }; + parser.encodePayload(packets, this.supportsBinary, function (data) { + self.doWrite(data, callbackfn); + }); + }; + Polling.prototype.uri = function () { + var query = this.query || {}; + var schema = this.secure ? 'https' : 'http'; + var port = ''; + if (false !== this.timestampRequests) { + query[this.timestampParam] = yeast(); + } + if (!this.supportsBinary && !query.sid) { + query.b64 = 1; + } + query = parseqs.encode(query); + if (this.port && ('https' === schema && Number(this.port) !== 443 || 'http' === schema && Number(this.port) !== 80)) { + port = ':' + this.port; + } + if (query.length) { + query = '?' + query; + } + var ipv6 = this.hostname.indexOf(':') !== -1; + return schema + '://' + (ipv6 ? '[' + this.hostname + ']' : this.hostname) + port + this.path + query; + }; +}); +/*engine.io-client@1.8.5#lib/transports/polling-xhr*/ +define('engine.io-client@1.8.5#lib/transports/polling-xhr', [ + 'require', + 'exports', + 'module', + 'xmlhttprequest-ssl', + './polling', + 'component-emitter', + 'component-inherit', + 'debug' +], function (require, exports, module) { + (function (global, require, exports, module) { + var XMLHttpRequest = require('xmlhttprequest-ssl'); + var Polling = require('./polling'); + var Emitter = require('component-emitter'); + var inherit = require('component-inherit'); + var debug = require('debug')('engine.io-client:polling-xhr'); + module.exports = XHR; + module.exports.Request = Request; + function empty() { + } + function XHR(opts) { + Polling.call(this, opts); + this.requestTimeout = opts.requestTimeout; + if (global.location) { + var isSSL = 'https:' === location.protocol; + var port = location.port; + if (!port) { + port = isSSL ? 443 : 80; + } + this.xd = opts.hostname !== global.location.hostname || port !== opts.port; + this.xs = opts.secure !== isSSL; + } else { + this.extraHeaders = opts.extraHeaders; + } + } + inherit(XHR, Polling); + XHR.prototype.supportsBinary = true; + XHR.prototype.request = function (opts) { + opts = opts || {}; + opts.uri = this.uri(); + opts.xd = this.xd; + opts.xs = this.xs; + opts.agent = this.agent || false; + opts.supportsBinary = this.supportsBinary; + opts.enablesXDR = this.enablesXDR; + opts.pfx = this.pfx; + opts.key = this.key; + opts.passphrase = this.passphrase; + opts.cert = this.cert; + opts.ca = this.ca; + opts.ciphers = this.ciphers; + opts.rejectUnauthorized = this.rejectUnauthorized; + opts.requestTimeout = this.requestTimeout; + opts.extraHeaders = this.extraHeaders; + return new Request(opts); + }; + XHR.prototype.doWrite = function (data, fn) { + var isBinary = typeof data !== 'string' && data !== undefined; + var req = this.request({ + method: 'POST', + data: data, + isBinary: isBinary + }); + var self = this; + req.on('success', fn); + req.on('error', function (err) { + self.onError('xhr post error', err); + }); + this.sendXhr = req; + }; + XHR.prototype.doPoll = function () { + debug('xhr poll'); + var req = this.request(); + var self = this; + req.on('data', function (data) { + self.onData(data); + }); + req.on('error', function (err) { + self.onError('xhr poll error', err); + }); + this.pollXhr = req; + }; + function Request(opts) { + this.method = opts.method || 'GET'; + this.uri = opts.uri; + this.xd = !!opts.xd; + this.xs = !!opts.xs; + this.async = false !== opts.async; + this.data = undefined !== opts.data ? opts.data : null; + this.agent = opts.agent; + this.isBinary = opts.isBinary; + this.supportsBinary = opts.supportsBinary; + this.enablesXDR = opts.enablesXDR; + this.requestTimeout = opts.requestTimeout; + this.pfx = opts.pfx; + this.key = opts.key; + this.passphrase = opts.passphrase; + this.cert = opts.cert; + this.ca = opts.ca; + this.ciphers = opts.ciphers; + this.rejectUnauthorized = opts.rejectUnauthorized; + this.extraHeaders = opts.extraHeaders; + this.create(); + } + Emitter(Request.prototype); + Request.prototype.create = function () { + var opts = { + agent: this.agent, + xdomain: this.xd, + xscheme: this.xs, + enablesXDR: this.enablesXDR + }; + opts.pfx = this.pfx; + opts.key = this.key; + opts.passphrase = this.passphrase; + opts.cert = this.cert; + opts.ca = this.ca; + opts.ciphers = this.ciphers; + opts.rejectUnauthorized = this.rejectUnauthorized; + var xhr = this.xhr = new XMLHttpRequest(opts); + var self = this; + try { + debug('xhr open %s: %s', this.method, this.uri); + xhr.open(this.method, this.uri, this.async); + try { + if (this.extraHeaders) { + xhr.setDisableHeaderCheck(true); + for (var i in this.extraHeaders) { + if (this.extraHeaders.hasOwnProperty(i)) { + xhr.setRequestHeader(i, this.extraHeaders[i]); + } + } + } + } catch (e) { + } + if (this.supportsBinary) { + xhr.responseType = 'arraybuffer'; + } + if ('POST' === this.method) { + try { + if (this.isBinary) { + xhr.setRequestHeader('Content-type', 'application/octet-stream'); + } else { + xhr.setRequestHeader('Content-type', 'text/plain;charset=UTF-8'); + } + } catch (e) { + } + } + try { + xhr.setRequestHeader('Accept', '*/*'); + } catch (e) { + } + if ('withCredentials' in xhr) { + xhr.withCredentials = true; + } + if (this.requestTimeout) { + xhr.timeout = this.requestTimeout; + } + if (this.hasXDR()) { + xhr.onload = function () { + self.onLoad(); + }; + xhr.onerror = function () { + self.onError(xhr.responseText); + }; + } else { + xhr.onreadystatechange = function () { + if (4 !== xhr.readyState) + return; + if (200 === xhr.status || 1223 === xhr.status) { + self.onLoad(); + } else { + setTimeout(function () { + self.onError(xhr.status); + }, 0); + } + }; + } + debug('xhr data %s', this.data); + xhr.send(this.data); + } catch (e) { + setTimeout(function () { + self.onError(e); + }, 0); + return; + } + if (global.document) { + this.index = Request.requestsCount++; + Request.requests[this.index] = this; + } + }; + Request.prototype.onSuccess = function () { + this.emit('success'); + this.cleanup(); + }; + Request.prototype.onData = function (data) { + this.emit('data', data); + this.onSuccess(); + }; + Request.prototype.onError = function (err) { + this.emit('error', err); + this.cleanup(true); + }; + Request.prototype.cleanup = function (fromError) { + if ('undefined' === typeof this.xhr || null === this.xhr) { + return; + } + if (this.hasXDR()) { + this.xhr.onload = this.xhr.onerror = empty; + } else { + this.xhr.onreadystatechange = empty; + } + if (fromError) { + try { + this.xhr.abort(); + } catch (e) { + } + } + if (global.document) { + delete Request.requests[this.index]; + } + this.xhr = null; + }; + Request.prototype.onLoad = function () { + var data; + try { + var contentType; + try { + contentType = this.xhr.getResponseHeader('Content-Type').split(';')[0]; + } catch (e) { + } + if (contentType === 'application/octet-stream') { + data = this.xhr.response || this.xhr.responseText; + } else { + if (!this.supportsBinary) { + data = this.xhr.responseText; + } else { + try { + data = String.fromCharCode.apply(null, new Uint8Array(this.xhr.response)); + } catch (e) { + var ui8Arr = new Uint8Array(this.xhr.response); + var dataArray = []; + for (var idx = 0, length = ui8Arr.length; idx < length; idx++) { + dataArray.push(ui8Arr[idx]); + } + data = String.fromCharCode.apply(null, dataArray); + } + } + } + } catch (e) { + this.onError(e); + } + if (null != data) { + this.onData(data); + } + }; + Request.prototype.hasXDR = function () { + return 'undefined' !== typeof global.XDomainRequest && !this.xs && this.enablesXDR; + }; + Request.prototype.abort = function () { + this.cleanup(); + }; + Request.requestsCount = 0; + Request.requests = {}; + if (global.document) { + if (global.attachEvent) { + global.attachEvent('onunload', unloadHandler); + } else if (global.addEventListener) { + global.addEventListener('beforeunload', unloadHandler, false); + } + } + function unloadHandler() { + for (var i in Request.requests) { + if (Request.requests.hasOwnProperty(i)) { + Request.requests[i].abort(); + } + } + } + }(function () { + return this; + }(), require, exports, module)); +}); +/*engine.io-client@1.8.5#lib/transports/polling-jsonp*/ +define('engine.io-client@1.8.5#lib/transports/polling-jsonp', [ + 'require', + 'exports', + 'module', + './polling', + 'component-inherit' +], function (require, exports, module) { + (function (global, require, exports, module) { + var Polling = require('./polling'); + var inherit = require('component-inherit'); + module.exports = JSONPPolling; + var rNewline = /\n/g; + var rEscapedNewline = /\\n/g; + var callbacks; + function empty() { + } + function JSONPPolling(opts) { + Polling.call(this, opts); + this.query = this.query || {}; + if (!callbacks) { + if (!global.___eio) + global.___eio = []; + callbacks = global.___eio; + } + this.index = callbacks.length; + var self = this; + callbacks.push(function (msg) { + self.onData(msg); + }); + this.query.j = this.index; + if (global.document && global.addEventListener) { + global.addEventListener('beforeunload', function () { + if (self.script) + self.script.onerror = empty; + }, false); + } + } + inherit(JSONPPolling, Polling); + JSONPPolling.prototype.supportsBinary = false; + JSONPPolling.prototype.doClose = function () { + if (this.script) { + this.script.parentNode.removeChild(this.script); + this.script = null; + } + if (this.form) { + this.form.parentNode.removeChild(this.form); + this.form = null; + this.iframe = null; + } + Polling.prototype.doClose.call(this); + }; + JSONPPolling.prototype.doPoll = function () { + var self = this; + var script = document.createElement('script'); + if (this.script) { + this.script.parentNode.removeChild(this.script); + this.script = null; + } + script.async = true; + script.src = this.uri(); + script.onerror = function (e) { + self.onError('jsonp poll error', e); + }; + var insertAt = document.getElementsByTagName('script')[0]; + if (insertAt) { + insertAt.parentNode.insertBefore(script, insertAt); + } else { + (document.head || document.body).appendChild(script); + } + this.script = script; + var isUAgecko = 'undefined' !== typeof navigator && /gecko/i.test(navigator.userAgent); + if (isUAgecko) { + setTimeout(function () { + var iframe = document.createElement('iframe'); + document.body.appendChild(iframe); + document.body.removeChild(iframe); + }, 100); + } + }; + JSONPPolling.prototype.doWrite = function (data, fn) { + var self = this; + if (!this.form) { + var form = document.createElement('form'); + var area = document.createElement('textarea'); + var id = this.iframeId = 'eio_iframe_' + this.index; + var iframe; + form.className = 'socketio'; + form.style.position = 'absolute'; + form.style.top = '-1000px'; + form.style.left = '-1000px'; + form.target = id; + form.method = 'POST'; + form.setAttribute('accept-charset', 'utf-8'); + area.name = 'd'; + form.appendChild(area); + document.body.appendChild(form); + this.form = form; + this.area = area; + } + this.form.action = this.uri(); + function complete() { + initIframe(); + fn(); + } + function initIframe() { + if (self.iframe) { + try { + self.form.removeChild(self.iframe); + } catch (e) { + self.onError('jsonp polling iframe removal error', e); + } + } + try { + var html = '