From 3b4fbb8efcb0da528460f3f3ab712dbb58488f37 Mon Sep 17 00:00:00 2001 From: Cherif BOUCHELAGHEM Date: Thu, 7 May 2020 21:20:59 +0100 Subject: [PATCH] 5.33.3 --- dist/bundles/can/test/test.css | 448 + dist/bundles/can/test/test.js | 96150 +++++++++++++++++++++++++++++++ dist/global/can.all.js | 43384 ++++++++++++++ dist/global/can.js | 30256 ++++++++++ dist/global/core.js | 30255 ++++++++++ dist/global/ecosystem.js | 43383 ++++++++++++++ dist/global/everything.js | 43383 ++++++++++++++ dist/steal.production.js | 12 + 8 files changed, 287271 insertions(+) create mode 100644 dist/bundles/can/test/test.css create mode 100644 dist/bundles/can/test/test.js create mode 100644 dist/global/can.all.js create mode 100644 dist/global/can.js create mode 100644 dist/global/core.js create mode 100644 dist/global/ecosystem.js create mode 100644 dist/global/everything.js create mode 100644 dist/steal.production.js diff --git a/dist/bundles/can/test/test.css b/dist/bundles/can/test/test.css new file mode 100644 index 00000000000..64212528768 --- /dev/null +++ b/dist/bundles/can/test/test.css @@ -0,0 +1,448 @@ +/*qunit@2.10.0#qunit/qunit.css!steal-css@1.3.2#css*/ +/*! + * QUnit 2.10.0 + * https://qunitjs.com/ + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license + * https://jquery.org/license + * + * Date: 2020-05-02T22:51Z + */ + +/** Font Family and Sizes */ + + +[id^=qunit] button { + font-size: initial; + border: initial; + background-color: buttonface; +} + +#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 (excluding toolbar) */ + +#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-banner { + height: 5px; +} + +#qunit-filteredTest { + padding: 0.5em 1em 0.5em 1em; + color: #366097; + background-color: #F4FF77; +} + +#qunit-userAgent { + padding: 0.5em 1em 0.5em 1em; + color: #FFF; + background-color: #2B81AF; + text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px; +} + + +/** Toolbar */ + +#qunit-testrunner-toolbar { + padding: 0.5em 1em 0.5em 1em; + color: #5E740B; + background-color: #EEE; +} + +#qunit-testrunner-toolbar .clearfix { + height: 0; + clear: both; +} + +#qunit-testrunner-toolbar label { + display: inline-block; +} + +#qunit-testrunner-toolbar input[type=checkbox], +#qunit-testrunner-toolbar input[type=radio] { + margin: 3px; + vertical-align: -2px; +} + +#qunit-testrunner-toolbar input[type=text] { + box-sizing: border-box; + height: 1.6em; +} + +#qunit-toolbar-filters { + float: right; +} + +.qunit-url-config, +.qunit-filter, +#qunit-modulefilter { + display: inline-block; + line-height: 2.1em; +} + +.qunit-filter, +#qunit-modulefilter { + position: relative; + margin-left: 1em; +} + +.qunit-url-config label { + margin-right: 0.5em; +} + +#qunit-modulefilter-search { + box-sizing: border-box; + min-width: 400px; +} + +#qunit-modulefilter-search-container:after { + position: absolute; + right: 0.3em; + content: "\25bc"; + color: black; +} + +#qunit-modulefilter-dropdown { + /* align with #qunit-modulefilter-search */ + box-sizing: border-box; + min-width: 400px; + position: absolute; + right: 0; + top: 50%; + margin-top: 0.8em; + + border: 1px solid #D3D3D3; + border-top: none; + border-radius: 0 0 .25em .25em; + color: #000; + background-color: #F5F5F5; + z-index: 99; +} + +#qunit-modulefilter-dropdown a { + color: inherit; + text-decoration: none; +} + +#qunit-modulefilter-dropdown .clickable.checked { + font-weight: bold; + color: #000; + background-color: #D2E0E6; +} + +#qunit-modulefilter-dropdown .clickable:hover { + color: #FFF; + background-color: #0D3349; +} + +#qunit-modulefilter-actions { + display: block; + overflow: auto; + + /* align with #qunit-modulefilter-dropdown-list */ + font: smaller/1.5em sans-serif; +} + +#qunit-modulefilter-dropdown #qunit-modulefilter-actions > * { + box-sizing: border-box; + max-height: 2.8em; + display: block; + padding: 0.4em; +} + +#qunit-modulefilter-dropdown #qunit-modulefilter-actions > button { + float: right; + font: inherit; +} + +#qunit-modulefilter-dropdown #qunit-modulefilter-actions > :last-child { + /* insert padding to align with checkbox margins */ + padding-left: 3px; +} + +#qunit-modulefilter-dropdown-list { + max-height: 200px; + overflow-y: auto; + margin: 0; + border-top: 2px groove threedhighlight; + padding: 0.4em 0 0; + font: smaller/1.5em sans-serif; +} + +#qunit-modulefilter-dropdown-list li { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +#qunit-modulefilter-dropdown-list .clickable { + display: block; + padding-left: 0.15em; + padding-right: 0.5em; +} + + +/** 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, +#qunit-tests li.aborted { + display: list-item; +} + +#qunit-tests.hidepass { + position: relative; +} + +#qunit-tests.hidepass li.running, +#qunit-tests.hidepass li.pass:not(.todo) { + 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 { + color: #374E0C; + background-color: #E0F2BE; + text-decoration: none; +} + +#qunit-tests ins { + color: #500; + background-color: #FFCACA; + 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; } + + +/*** Aborted tests */ +#qunit-tests .aborted { color: #000; background-color: orange; } +/*** Skipped tests */ + +#qunit-tests .skipped { + background-color: #EBECE9; +} + +#qunit-tests .qunit-todo-label, +#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; +} + +#qunit-tests .qunit-todo-label { + background-color: #EEE; +} + +/** Result */ + +#qunit-testresult { + color: #2B81AF; + background-color: #D2E0E6; + + border-bottom: 1px solid #FFF; +} +#qunit-testresult .clearfix { + height: 0; + clear: both; +} +#qunit-testresult .module-name { + font-weight: 700; +} +#qunit-testresult-display { + padding: 0.5em 1em 0.5em 1em; + width: 85%; + float:left; +} +#qunit-testresult-controls { + padding: 0.5em 1em 0.5em 1em; + width: 10%; + float:left; +} + +/** 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..91d2378e7d0 --- /dev/null +++ b/dist/bundles/can/test/test.js @@ -0,0 +1,96150 @@ +/*[system-bundles-config]*/ +System.bundles = {"bundles/can/test/test.css!":["qunit@2.10.0#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) { + if (utils.path.endsWithSlash(pkg.main)) { + main = pkg.main + 'index'; + } else { + 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 addNpmExtension(System) { + if (System._extensions) { + System._extensions.push(addNpmExtension); + } + 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 nameIsNpmModule = utils.moduleName.isNpm(name); + var parentIsNpmModule = utils.moduleName.isNpm(parentName); + var identifierEndsWithSlash = utils.path.endsWithSlash(name); + if (nameIsNpmModule && parentModuleName) { + return oldNormalize.call(this, name, parentName, parentAddress, pluginNormalize); + } + 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; + newError.stack = newError.stack + error.stack; + 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.33.2#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.33.2', + '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@2.3.0#dist/socket.io': { 'format': 'cjs' }, + 'socket.io-client/dist/socket.io': { 'format': 'cjs' } + }, + 'configDependencies': ['./node_modules/steal-conditional/conditional.js'], + 'plugins': ['steal-stache'], + 'main': 'can' + }, + 'resolutions': { + 'can': '5.33.2', + 'can-component': '4.6.2', + 'can-stache-bindings': '4.10.9', + 'can-define': '2.8.0', + 'can-query-logic': '1.2.2', + 'can-value': '1.1.1', + 'can-ajax': '2.4.6', + 'can-assign': '1.3.3', + 'can-bind': '1.5.1', + 'can-construct': '3.5.6', + 'can-construct-super': '3.2.1', + 'can-define-lazy-value': '1.1.1', + 'can-control': '4.4.3', + 'can-deparam': '1.2.1', + 'can-dom-events': '1.3.11', + 'can-dom-mutate': '1.3.11', + 'can-event-dom-enter': '2.2.1', + 'can-event-dom-radiochange': '2.2.1', + 'can-event-queue': '1.1.7', + 'can-globals': '1.2.2', + 'can-key': '1.2.1', + 'can-key-tree': '1.2.2', + 'can-param': '1.1.2', + 'can-parse-uri': '1.2.2', + 'can-queues': '1.3.1', + 'can-reflect-dependencies': '1.1.2', + 'can-reflect-promise': '2.2.1', + 'can-simple-dom': '1.7.0', + 'can-simple-observable': '2.5.0', + 'can-stache-key': '1.4.3', + 'can-validate-interface': '1.0.3', + 'can-view-live': '4.2.8', + 'can-view-model': '4.0.3', + 'can-view-nodelist': '4.3.4', + 'can-view-parser': '4.1.3', + 'can-view-scope': '4.13.6', + 'can-view-target': '4.1.6', + 'can-stache-converters': '4.2.6', + 'can-compute': '4.1.1', + 'can-list': '4.2.2', + 'can-map': '4.3.9', + 'can-map-define': '4.4.0', + 'can-fixture': '3.1.7', + 'can-fixture-socket': '2.0.3', + 'can-kefir': '1.1.4', + 'can-stream': '1.1.1', + 'can-stream-kefir': '1.2.1', + 'can-ndjson-stream': '1.0.2', + 'can-define-backup': '2.1.2', + 'can-define-stream': '1.1.1', + 'can-define-stream-kefir': '1.1.1', + 'can-validate': '1.2.1', + 'can-validate-validatejs': '1.0.1', + 'can-define-validate-validatejs': '1.1.1', + 'can-view-autorender': '5.0.4' + }, + '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@2.3.0#dist/socket.io': { 'format': 'cjs' }, + 'socket.io-client/dist/socket.io': { 'format': 'cjs' } + }, + 'configDependencies': ['./node_modules/steal-conditional/conditional.js'], + 'plugins': ['steal-stache'], + 'main': 'can' + } + }, + { + 'name': 'steal-stache', + 'version': '4.1.5', + 'fileUrl': './node_modules/steal-stache/package.json', + 'main': 'steal-stache.js', + 'steal': { + 'main': 'steal-stache', + 'configDependencies': ['live-reload'], + 'npmIgnore': { + 'documentjs': true, + 'testee': true, + 'steal-tools': true + }, + 'npmAlgorithm': 'flat', + 'ext': { 'stache': 'steal-stache' } + }, + 'resolutions': {} + }, + { + 'name': 'steal', + 'version': '2.2.4', + '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.6.0', + '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': 'os-browserify', + 'version': '0.3.0', + 'fileUrl': './node_modules/os-browserify/package.json', + 'main': 'main.js', + 'browser': 'browser.js', + 'jspm': {}, + 'resolutions': {} + }, + { + 'name': 'https-browserify', + 'version': '1.0.0', + 'fileUrl': './node_modules/https-browserify/package.json', + 'main': 'index.js', + 'resolutions': {} + }, + { + 'name': 'path-browserify', + 'version': '0.0.1', + 'fileUrl': './node_modules/path-browserify/package.json', + 'main': 'index.js', + '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': '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': 'buffer', + 'version': '5.0.8', + 'fileUrl': './node_modules/steal/node_modules/buffer/package.json', + 'main': 'index.js', + 'jspm': {}, + '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-component', + 'version': '4.6.2', + 'fileUrl': './node_modules/can-component/package.json', + 'main': 'can-component', + 'steal': {}, + 'resolutions': { + 'can-component': '4.6.2', + 'can-view-model': '4.0.3', + 'can-define': '2.8.0', + 'can-view-scope': '4.13.6', + 'can-simple-observable': '2.5.0', + 'can-dom-events': '1.3.11', + 'can-dom-mutate': '1.3.11', + 'can-construct': '3.5.6', + 'can-queues': '1.3.1', + 'can-value': '1.1.1', + 'can-globals': '1.2.2', + 'can-bind': '1.5.1', + 'can-simple-map': '4.3.2', + 'can-stache': '4.17.21', + 'can-dom-data': '1.0.3', + 'can-view-callbacks': '4.4.1', + 'can-observe': '2.3.1', + 'steal-qunit': '2.0.0', + 'can-reflect': '1.18.0', + 'can-symbol': '1.6.5', + 'can-fragment': '1.3.1', + 'can-log': '1.0.2', + 'can-test-helpers': '1.1.4', + 'can-namespace': '1.0.0', + 'can-stache-bindings': '4.10.9', + 'can-view-nodelist': '4.3.4', + 'can-assign': '1.3.3', + 'can-observation-recorder': '1.3.1', + 'can-child-nodes': '1.2.1', + 'can-string': '1.1.0', + 'can-vdom': '4.4.2', + 'can-control': '4.4.3' + } + }, + { + 'name': 'can-stache-bindings', + 'version': '4.10.9', + 'fileUrl': './node_modules/can-stache-bindings/package.json', + 'main': 'can-stache-bindings', + 'steal': { 'main': 'can-stache-bindings' }, + 'resolutions': { + 'can-stache-bindings': '4.10.9', + 'can-dom-mutate': '1.3.11', + 'can-globals': '1.2.2', + 'can-stache': '4.17.21', + 'can-dom-events': '1.3.11', + 'can-simple-map': '4.3.2', + 'can-attribute-encoder': '1.1.4', + 'can-test-helpers': '1.1.4', + 'can-define': '2.8.0', + 'can-view-model': '4.0.3', + 'can-simple-observable': '2.5.0', + 'can-symbol': '1.6.5', + 'can-reflect': '1.18.0', + 'can-view-callbacks': '4.4.1', + 'can-dom-data': '1.0.3', + 'can-event-dom-enter': '2.2.1', + 'can-queues': '1.3.1', + 'can-view-scope': '4.13.6', + 'can-reflect-dependencies': '1.1.2', + 'steal-qunit': '2.0.0', + 'can-bind': '1.5.1', + 'can-stache-key': '1.4.3', + 'can-observation-recorder': '1.3.1', + 'can-assign': '1.3.3', + 'can-log': '1.0.2', + 'can-view-nodelist': '4.3.4', + 'can-event-queue': '1.1.7', + 'can-vdom': '4.4.2', + 'can-attribute-observable': '1.2.7' + } + }, + { + 'name': 'can-define', + 'version': '2.8.0', + 'fileUrl': './node_modules/can-define/package.json', + 'main': 'can-define.js', + 'resolutions': { + 'can-define': '2.8.0', + 'can-queues': '1.3.1', + 'can-simple-observable': '2.5.0', + 'can-assign': '1.3.3', + 'can-reflect': '1.18.0', + 'can-data-types': '1.2.1', + 'steal-qunit': '2.0.0', + 'can-symbol': '1.6.5', + 'can-test-helpers': '1.1.4', + 'can-observation-recorder': '1.3.1', + 'can-observation': '4.2.0', + 'can-log': '1.0.2', + 'can-reflect-tests': '1.0.0', + 'can-construct': '3.5.6', + 'can-namespace': '1.0.0', + 'can-event-queue': '1.1.7', + 'can-string-to-any': '1.2.1', + 'can-define-lazy-value': '1.1.1', + 'can-diff': '1.5.0', + 'can-single-reference': '1.3.0' + } + }, + { + 'name': 'can-query-logic', + 'version': '1.2.2', + '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.2.2', + 'can-reflect': '1.18.0', + 'steal-qunit': '2.0.0', + 'can-assign': '1.3.3', + 'can-test-helpers': '1.1.4', + 'can-symbol': '1.6.5', + 'can-define-lazy-value': '1.1.1', + 'can-key': '1.2.1', + 'can-log': '1.0.2' + } + }, + { + 'name': 'can-value', + 'version': '1.1.1', + '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.1', + 'can-reflect-dependencies': '1.1.2', + 'can-reflect': '1.18.0', + 'can-simple-map': '4.3.2', + 'steal-qunit': '2.0.0', + 'can-key': '1.2.1', + 'can-simple-observable': '2.5.0', + 'can-namespace': '1.0.0', + 'can-observation': '4.2.0' + } + }, + { + 'name': 'can-ajax', + 'version': '2.4.6', + 'fileUrl': './node_modules/can-ajax/package.json', + 'main': 'can-ajax', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'steal-tools': true + }, + 'main': 'can-ajax' + }, + 'resolutions': { + 'can-ajax': '2.4.6', + 'can-globals': '1.2.2', + 'can-parse-uri': '1.2.2', + 'can-namespace': '1.0.0', + 'can-make-map': '1.2.2', + 'can-reflect': '1.18.0', + 'can-param': '1.1.2', + 'steal-qunit': '2.0.0', + 'qunit': '2.10.0' + } + }, + { + 'name': 'can-assign', + 'version': '1.3.3', + 'fileUrl': './node_modules/can-assign/package.json', + 'main': 'can-assign', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + } + }, + 'resolutions': { + 'can-assign': '1.3.3', + 'steal-qunit': '2.0.0', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-bind', + 'version': '1.5.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.5.1', + 'can-reflect': '1.18.0', + 'can-reflect-dependencies': '1.1.2', + 'can-simple-observable': '2.5.0', + 'can-simple-map': '4.3.2', + 'can-queues': '1.3.1', + 'can-value': '1.1.1', + 'can-observation': '4.2.0', + 'can-test-helpers': '1.1.4', + 'steal-qunit': '2.0.0', + 'can-symbol': '1.6.5', + 'can-namespace': '1.0.0', + 'can-assign': '1.3.3', + 'can-log': '1.0.2' + } + }, + { + 'name': 'can-construct', + 'version': '3.5.6', + 'fileUrl': './node_modules/can-construct/package.json', + 'main': 'can-construct', + 'steal': {}, + 'resolutions': { + 'can-construct': '3.5.6', + 'can-log': '1.0.2', + 'steal-qunit': '2.0.0', + 'can-reflect': '1.18.0', + 'can-namespace': '1.0.0', + 'can-symbol': '1.6.5', + 'can-string': '1.1.0' + } + }, + { + 'name': 'can-construct-super', + 'version': '3.2.1', + '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.1', + 'steal-qunit': '2.0.0', + 'can-reflect': '1.18.0', + 'can-construct': '3.5.6' + } + }, + { + 'name': 'can-define-lazy-value', + 'version': '1.1.1', + '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.1', + 'steal-qunit': '2.0.0' + } + }, + { + 'name': 'can-control', + 'version': '4.4.3', + 'fileUrl': './node_modules/can-control/package.json', + 'main': 'can-control', + 'resolutions': { + 'can-control': '4.4.3', + 'can-dom-events': '1.3.11', + 'can-dom-mutate': '1.3.11', + 'can-globals': '1.2.2', + 'can-define': '2.8.0', + 'can-simple-observable': '2.5.0', + 'can-simple-map': '4.3.2', + 'can-fragment': '1.3.1', + 'can-symbol': '1.6.5', + 'steal-qunit': '2.0.0', + 'can-log': '1.0.2', + 'can-construct': '3.5.6', + 'can-namespace': '1.0.0', + 'can-assign': '1.3.3', + 'can-stache-key': '1.4.3', + 'can-reflect': '1.18.0', + 'can-observation': '4.2.0', + 'can-event-queue': '1.1.7', + 'can-key': '1.2.1', + 'can-string': '1.1.0' + } + }, + { + 'name': 'can-deparam', + 'version': '1.2.1', + '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.1', + 'can-string-to-any': '1.2.1', + 'steal-qunit': '2.0.0', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-dom-events', + 'version': '1.3.11', + 'fileUrl': './node_modules/can-dom-events/package.json', + 'main': 'can-dom-events', + 'resolutions': { + 'can-dom-events': '1.3.11', + 'steal-qunit': '2.0.0', + 'can-namespace': '1.0.0', + 'jquery': '3.5.1', + 'can-globals': '1.2.2', + 'can-key-tree': '1.2.2', + 'can-reflect': '1.18.0' + } + }, + { + 'name': 'can-dom-mutate', + 'version': '1.3.11', + 'fileUrl': './node_modules/can-dom-mutate/package.json', + 'main': 'can-dom-mutate', + 'steal': { 'main': 'can-dom-mutate' }, + 'resolutions': { + 'can-dom-mutate': '1.3.11', + 'steal-qunit': '2.0.0', + 'can-globals': '1.2.2', + 'can-dom-events': '1.3.11', + 'can-namespace': '1.0.0', + 'can-reflect': '1.18.0' + } + }, + { + 'name': 'can-event-dom-enter', + 'version': '2.2.1', + '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.11', + 'can-event-dom-enter': '2.2.1', + 'can-namespace': '1.0.0', + 'steal-qunit': '2.0.0' + } + }, + { + 'name': 'can-event-dom-radiochange', + 'version': '2.2.1', + '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.11', + 'can-event-dom-radiochange': '2.2.1', + 'steal-qunit': '2.0.0', + 'can-namespace': '1.0.0', + 'can-globals': '1.2.2' + } + }, + { + 'name': 'can-event-queue', + 'version': '1.1.7', + '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.7', + 'can-queues': '1.3.1', + 'can-dom-events': '1.3.11', + 'can-symbol': '1.6.5', + 'can-reflect': '1.18.0', + 'steal-qunit': '2.0.0', + 'can-log': '1.0.2', + 'can-key-tree': '1.2.2', + 'can-define-lazy-value': '1.1.1' + } + }, + { + 'name': 'can-globals', + 'version': '1.2.2', + 'fileUrl': './node_modules/can-globals/package.json', + 'main': 'can-globals.js', + 'resolutions': { + 'can-globals': '1.2.2', + 'can-reflect': '1.18.0', + 'qunit': '2.10.0', + 'steal-qunit': '2.0.0', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-key', + 'version': '1.2.1', + '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.1', + 'can-reflect': '1.18.0', + 'steal-qunit': '2.0.0', + 'can-symbol': '1.6.5', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-key-tree', + 'version': '1.2.2', + 'fileUrl': './node_modules/can-key-tree/package.json', + 'main': '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.2', + 'steal-qunit': '2.0.0', + 'can-reflect': '1.18.0' + } + }, + { + 'name': 'can-param', + 'version': '1.1.2', + '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.2', + 'steal-qunit': '2.0.0', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-parse-uri', + 'version': '1.2.2', + '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.2', + 'steal-qunit': '2.0.0', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-queues', + 'version': '1.3.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.3.1', + 'can-test-helpers': '1.1.4', + 'steal-qunit': '2.0.0', + 'can-log': '1.0.2', + 'can-namespace': '1.0.0', + 'can-symbol': '1.6.5', + 'can-assign': '1.3.3' + } + }, + { + 'name': 'can-reflect-dependencies', + 'version': '1.1.2', + 'fileUrl': './node_modules/can-reflect-dependencies/package.json', + 'main': 'can-reflect-dependencies.js', + 'resolutions': { + 'can-simple-observable': '2.5.0', + 'can-reflect-dependencies': '1.1.2', + 'steal-qunit': '2.0.0', + 'can-simple-map': '4.3.2', + 'can-reflect': '1.18.0', + 'can-symbol': '1.6.5', + 'can-assign': '1.3.3' + } + }, + { + 'name': 'can-reflect-promise', + 'version': '2.2.1', + 'fileUrl': './node_modules/can-reflect-promise/package.json', + 'main': 'can-reflect-promise', + 'steal': { 'npmAlgorithm': 'flat' }, + 'resolutions': { + 'can-globals': '1.2.2', + 'can-reflect-promise': '2.2.1', + 'can-symbol': '1.6.5', + 'can-test-helpers': '1.1.4', + 'can-observation-recorder': '1.3.1', + 'steal-qunit': '2.0.0', + 'can-reflect': '1.18.0', + 'can-queues': '1.3.1', + 'can-key-tree': '1.2.2', + 'can-log': '1.0.2' + } + }, + { + 'name': 'can-simple-dom', + 'version': '1.7.0', + 'fileUrl': './node_modules/can-simple-dom/package.json', + 'main': 'can-simple-dom.js', + 'resolutions': { + 'can-simple-dom': '1.7.0', + 'steal-qunit': '2.0.0', + 'he': '1.2.0', + 'simple-html-tokenizer': '0.2.6', + 'can-child-nodes': '1.2.1', + 'micro-location': '0.1.5' + } + }, + { + 'name': 'can-simple-observable', + 'version': '2.5.0', + 'fileUrl': './node_modules/can-simple-observable/package.json', + 'main': 'can-simple-observable', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'steal-tools': true + } + }, + 'resolutions': { + 'can-simple-observable': '2.5.0', + 'can-reflect': '1.18.0', + 'can-symbol': '1.6.5', + 'steal-qunit': '2.0.0', + 'can-observation-recorder': '1.3.1', + 'can-namespace': '1.0.0', + 'can-event-queue': '1.1.7', + 'can-observation': '4.2.0', + 'can-queues': '1.3.1', + 'can-key': '1.2.1', + 'can-reflect-dependencies': '1.1.2', + 'can-log': '1.0.2' + } + }, + { + 'name': 'can-stache-key', + 'version': '1.4.3', + '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.3', + 'can-event-queue': '1.1.7', + 'can-simple-observable': '2.5.0', + 'can-reflect': '1.18.0', + 'can-test-helpers': '1.1.4', + 'can-observation': '4.2.0', + 'steal-qunit': '2.0.0', + 'can-observation-recorder': '1.3.1', + 'can-simple-map': '4.3.2', + 'can-log': '1.0.2', + 'can-symbol': '1.6.5', + 'can-reflect-promise': '2.2.1' + } + }, + { + 'name': 'can-validate-interface', + 'version': '1.0.3', + 'fileUrl': './node_modules/can-validate-interface/package.json', + 'main': 'index.js', + 'resolutions': { + 'can-validate-interface': '1.0.3', + 'steal-qunit': '2.0.0' + } + }, + { + 'name': 'can-view-live', + 'version': '4.2.8', + '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.8', + 'can-define': '2.8.0', + 'can-observation': '4.2.0', + 'can-simple-observable': '2.5.0', + 'can-view-nodelist': '4.3.4', + 'can-test-helpers': '1.1.4', + 'can-dom-mutate': '1.3.11', + 'can-reflect-dependencies': '1.1.2', + 'can-symbol': '1.6.5', + 'can-fragment': '1.3.1', + 'can-queues': '1.3.1', + 'can-simple-map': '4.3.2', + 'can-reflect': '1.18.0', + 'can-globals': '1.2.2', + 'steal-qunit': '2.0.0', + 'can-diff': '1.5.0', + 'can-view-parser': '4.1.3', + 'can-child-nodes': '1.2.1', + 'can-attribute-observable': '1.2.7', + 'can-view-callbacks': '4.4.1' + } + }, + { + 'name': 'can-view-model', + 'version': '4.0.3', + 'fileUrl': './node_modules/can-view-model/package.json', + 'main': 'can-view-model', + 'resolutions': { + 'can-view-model': '4.0.3', + 'can-simple-map': '4.3.2', + 'steal-qunit': '2.0.0', + 'can-namespace': '1.0.0', + 'can-globals': '1.2.2', + 'can-reflect': '1.18.0', + 'can-symbol': '1.6.5' + } + }, + { + 'name': 'can-view-nodelist', + 'version': '4.3.4', + 'fileUrl': './node_modules/can-view-nodelist/package.json', + 'main': 'can-view-nodelist', + 'resolutions': { + 'can-view-nodelist': '4.3.4', + 'can-reflect': '1.18.0', + 'can-fragment': '1.3.1', + 'steal-qunit': '2.0.0', + 'can-namespace': '1.0.0', + 'can-dom-mutate': '1.3.11' + } + }, + { + 'name': 'can-view-parser', + 'version': '4.1.3', + 'fileUrl': './node_modules/can-view-parser/package.json', + 'main': 'can-view-parser', + 'resolutions': { + 'can-view-parser': '4.1.3', + 'can-test-helpers': '1.1.4', + 'can-attribute-encoder': '1.1.4', + 'steal-qunit': '2.0.0', + 'can-log': '1.0.2', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-view-scope', + 'version': '4.13.6', + 'fileUrl': './node_modules/can-view-scope/package.json', + 'main': 'can-view-scope', + 'resolutions': { + 'can-view-scope': '4.13.6', + 'can-stache-key': '1.4.3', + 'can-simple-observable': '2.5.0', + 'can-reflect-dependencies': '1.1.2', + 'can-reflect': '1.18.0', + 'can-simple-map': '4.3.2', + 'can-observation-recorder': '1.3.1', + 'can-observation': '4.2.0', + 'can-stache-helpers': '1.2.0', + 'can-symbol': '1.6.5', + 'steal-qunit': '2.0.0', + 'can-test-helpers': '1.1.4', + 'can-assign': '1.3.3', + 'can-namespace': '1.0.0', + 'can-log': '1.0.2', + 'can-define-lazy-value': '1.1.1', + 'can-event-queue': '1.1.7', + 'can-single-reference': '1.3.0' + } + }, + { + 'name': 'can-view-target', + 'version': '4.1.6', + 'fileUrl': './node_modules/can-view-target/package.json', + 'main': 'can-view-target', + 'resolutions': { + 'can-view-target': '4.1.6', + 'can-simple-dom': '1.7.0', + 'can-globals': '1.2.2', + 'steal-qunit': '2.0.0', + 'can-dom-mutate': '1.3.11', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-stache-converters', + 'version': '4.2.6', + 'fileUrl': './node_modules/can-stache-converters/package.json', + 'main': 'can-stache-converters', + 'steal': { 'main': 'can-stache-converters' }, + 'resolutions': { + 'can-stache-converters': '4.2.6', + 'can-define': '2.8.0', + 'can-dom-events': '1.3.11', + 'can-reflect': '1.18.0', + 'can-compute': '4.1.1', + 'can-stache': '4.17.21', + 'steal-qunit': '2.0.0', + 'can-string-to-any': '1.2.1', + 'can-log': '1.0.2', + 'can-stache-bindings': '4.10.9', + 'can-stache-helpers': '1.2.0' + } + }, + { + 'name': 'can-compute', + 'version': '4.1.1', + 'fileUrl': './node_modules/can-compute/package.json', + 'main': 'can-compute', + 'resolutions': { + 'can-compute': '4.1.1', + 'can-event-queue': '1.1.7', + 'can-queues': '1.3.1', + 'can-dom-events': '1.3.11', + 'can-reflect': '1.18.0', + 'steal-qunit': '2.0.0', + 'can-observation-recorder': '1.3.1', + 'can-symbol': '1.6.5', + 'can-namespace': '1.0.0', + 'can-observation': '4.2.0', + 'can-stache-key': '1.4.3', + 'can-key': '1.2.1', + 'can-assign': '1.3.3', + 'can-single-reference': '1.3.0' + } + }, + { + 'name': 'can-list', + 'version': '4.2.2', + 'fileUrl': './node_modules/can-list/package.json', + 'main': 'can-list', + 'steal': { 'npmAlgorithm': 'flat' }, + 'resolutions': { + 'can-list': '4.2.2', + 'can-map': '4.3.9', + 'can-reflect': '1.18.0', + 'can-symbol': '1.6.5', + 'steal-qunit': '2.0.0', + 'can-observation': '4.2.0', + 'can-namespace': '1.0.0', + 'can-queues': '1.3.1', + 'can-event-queue': '1.1.7', + 'can-observation-recorder': '1.3.1', + 'can-assign': '1.3.3', + 'can-cid': '1.3.1', + 'can-types': '1.4.0' + } + }, + { + 'name': 'can-map', + 'version': '4.3.9', + 'fileUrl': './node_modules/can-map/package.json', + 'main': 'can-map', + 'steal': {}, + 'resolutions': { + 'can-map': '4.3.9', + 'can-compute': '4.1.1', + 'can-construct': '3.5.6', + 'can-stache-key': '1.4.3', + 'can-queues': '1.3.1', + 'can-test-helpers': '1.1.4', + 'can-observation-recorder': '1.3.1', + 'can-reflect-tests': '1.0.0', + 'steal-qunit': '2.0.0', + 'can-reflect': '1.18.0', + 'can-symbol': '1.6.5', + 'can-event-queue': '1.1.7', + 'can-observation': '4.2.0', + 'can-namespace': '1.0.0', + 'can-log': '1.0.2', + 'can-assign': '1.3.3', + 'can-cid': '1.3.1', + 'can-types': '1.4.0', + 'can-single-reference': '1.3.0' + } + }, + { + 'name': 'can-map-define', + 'version': '4.4.0', + 'fileUrl': './node_modules/can-map-define/package.json', + 'main': 'can-map-define', + 'steal': { 'main': 'can-map-define' }, + 'resolutions': { + 'can-key': '1.2.1', + 'can-map': '4.3.9', + 'can-list': '4.2.2', + 'can-compute': '4.1.1', + 'can-map-define': '4.4.0', + 'can-reflect': '1.18.0', + 'steal-qunit': '2.0.0', + 'can-reflect-tests': '1.0.0', + 'can-log': '1.0.2', + 'can-assign': '1.3.3', + 'can-event-queue': '1.1.7', + 'can-queues': '1.3.1', + 'can-observation-recorder': '1.3.1', + 'can-simple-observable': '2.5.0', + 'can-symbol': '1.6.5' + } + }, + { + 'name': 'can-fixture', + 'version': '3.1.7', + 'fileUrl': './node_modules/can-fixture/package.json', + 'main': 'fixture.js', + 'resolutions': { + 'can-fixture': '3.1.7', + 'can-query-logic': '1.2.2', + 'can-define': '2.8.0', + 'can-reflect': '1.18.0', + 'can-set-legacy': '1.0.1', + 'jquery': '3.5.1', + 'steal-qunit': '2.0.0', + 'can-log': '1.0.2', + 'can-test-helpers': '1.1.4', + 'can-namespace': '1.0.0', + 'can-key': '1.2.1', + 'can-deparam': '1.2.1', + 'can-memory-store': '1.0.2' + } + }, + { + 'name': 'can-fixture-socket', + 'version': '2.0.3', + '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 + }, + 'paths': { '@feathersjs/commons*lib/lib': 'node_modules/@feathersjs/commons/lib/index.js' }, + 'main': 'can-fixture-socket' + }, + 'resolutions': { + 'can-fixture-socket': '2.0.3', + 'can-fixture': '3.1.7', + 'socket.io-client': '2.3.0', + '@feathersjs/feathers': '3.3.1', + '@feathersjs/socketio-client': '1.2.1', + 'es6-promise-polyfill': '1.2.0', + 'object-assign': '4.1.1', + 'steal-qunit': '2.0.0', + 'can-set-legacy': '1.0.1', + 'can-assign': '1.3.3' + } + }, + { + 'name': 'can-kefir', + 'version': '1.1.4', + 'fileUrl': './node_modules/can-kefir/package.json', + 'main': 'can-kefir', + 'browser': {}, + 'resolutions': { + 'can-kefir': '1.1.4', + 'can-queues': '1.3.1', + 'can-reflect': '1.18.0', + 'steal-qunit': '2.0.0', + 'can-symbol': '1.6.5', + 'can-event-queue': '1.1.7', + 'can-observation-recorder': '1.3.1', + 'kefir': '3.8.6' + } + }, + { + 'name': 'can-stream', + 'version': '1.1.1', + 'fileUrl': './node_modules/can-stream/package.json', + 'main': 'can-stream', + 'steal': {}, + 'resolutions': { + 'can-compute': '4.1.1', + 'can-define': '2.8.0', + 'can-stream': '1.1.1', + 'steal-qunit': '2.0.0', + 'can-assign': '1.3.3', + 'can-reflect': '1.18.0', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-stream-kefir', + 'version': '1.2.1', + 'fileUrl': './node_modules/can-stream-kefir/package.json', + 'main': 'can-stream-kefir', + 'steal': {}, + 'resolutions': { + 'can-stream-kefir': '1.2.1', + 'can-compute': '4.1.1', + 'can-define': '2.8.0', + 'steal-qunit': '2.0.0', + 'can-reflect': '1.18.0', + 'can-kefir': '1.1.4', + 'can-stream': '1.1.1', + 'can-symbol': '1.6.5', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-ndjson-stream', + 'version': '1.0.2', + '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.2', + 'steal-qunit': '2.0.0', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-define-backup', + 'version': '2.1.2', + 'fileUrl': './node_modules/can-define-backup/package.json', + 'main': 'can-define-backup', + 'resolutions': { + 'can-define': '2.8.0', + 'can-define-backup': '2.1.2', + 'can-reflect': '1.18.0', + 'can-observation': '4.2.0', + 'steal-qunit': '2.0.0', + 'can-simple-observable': '2.5.0', + 'can-diff': '1.5.0' + } + }, + { + 'name': 'can-define-stream', + 'version': '1.1.1', + 'fileUrl': './node_modules/can-define-stream/package.json', + 'main': 'can-define-stream', + 'steal': {}, + 'resolutions': { + 'can-define': '2.8.0', + 'can-define-stream': '1.1.1', + 'can-compute': '4.1.1', + 'can-stream': '1.1.1', + 'can-symbol': '1.6.5', + 'steal-qunit': '2.0.0', + 'can-assign': '1.3.3', + 'can-reflect': '1.18.0' + } + }, + { + 'name': 'can-define-stream-kefir', + 'version': '1.1.1', + 'fileUrl': './node_modules/can-define-stream-kefir/package.json', + 'main': 'can-define-stream-kefir', + 'steal': {}, + 'resolutions': { + 'can-define': '2.8.0', + 'can-define-stream-kefir': '1.1.1', + 'steal-qunit': '2.0.0', + 'can-symbol': '1.6.5', + 'can-namespace': '1.0.0', + 'can-define-stream': '1.1.1', + 'can-stream-kefir': '1.2.1' + } + }, + { + 'name': 'can-validate', + 'version': '1.2.1', + '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.1', + 'steal-qunit': '2.0.0', + 'can-reflect': '1.18.0' + } + }, + { + 'name': 'can-validate-validatejs', + 'version': '1.0.1', + '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.1', + 'steal-qunit': '2.0.0', + 'can-reflect': '1.18.0', + '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-define-validate-validatejs', + 'version': '1.1.1', + '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.1', + 'can-define': '2.8.0', + 'can-compute': '4.1.1', + 'steal-qunit': '2.0.0', + 'can-assign': '1.3.3', + 'can-reflect': '1.18.0', + 'can-validate': '1.2.1', + 'can-validate-validatejs': '0.1.3' + } + }, + { + 'name': 'can-view-autorender', + 'version': '5.0.4', + 'fileUrl': './node_modules/can-view-autorender/package.json', + 'main': 'can-view-autorender', + 'resolutions': { + 'can-view-autorender': '5.0.4', + 'steal-qunit': '2.0.0' + } + }, + { + 'name': 'steal-qunit', + 'version': '2.0.0', + 'fileUrl': './node_modules/steal-qunit/package.json', + 'main': 'steal-qunit', + 'steal': { + 'plugins': ['steal-css'], + 'meta': { + 'qunit@2.10.0#qunit/qunit': { + 'format': 'global', + 'exports': 'QUnit', + 'deps': ['steal-qunit/add-dom'] + } + } + }, + 'resolutions': { + 'qunit': '2.10.0', + 'steal-css': '1.3.2' + }, + 'system': { + 'plugins': ['steal-css'], + 'meta': { + 'qunit@2.10.0#qunit/qunit': { + 'format': 'global', + 'exports': 'QUnit', + 'deps': ['steal-qunit/add-dom'] + } + } + } + }, + { + 'name': 'can-reflect', + 'version': '1.18.0', + 'fileUrl': './node_modules/can-reflect/package.json', + 'main': 'can-reflect', + 'resolutions': { + 'can-reflect': '1.18.0', + 'can-namespace': '1.0.0', + 'can-symbol': '1.6.5' + } + }, + { + 'name': 'can-simple-map', + 'version': '4.3.2', + '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.6', + 'can-event-queue': '1.1.7', + 'can-queues': '1.3.1', + 'can-observation-recorder': '1.3.1', + 'can-reflect': '1.18.0', + 'can-log': '1.0.2', + 'can-symbol': '1.6.5' + } + }, + { + '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.2', + 'fileUrl': './node_modules/can-make-map/package.json', + 'main': '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.2', + 'fileUrl': './node_modules/can-log/package.json', + 'main': 'can-log', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'main': 'can-log' + }, + 'resolutions': { 'can-log': '1.0.2' } + }, + { + 'name': 'can-fragment', + 'version': '1.3.1', + '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.2', + 'can-namespace': '1.0.0', + 'can-reflect': '1.18.0', + 'can-symbol': '1.6.5', + 'can-child-nodes': '1.2.1' + } + }, + { + 'name': 'can-symbol', + 'version': '1.6.5', + '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-namespace': '1.0.0' } + }, + { + 'name': 'can-string-to-any', + 'version': '1.2.1', + '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.4', + 'fileUrl': './node_modules/can-test-helpers/package.json', + 'main': 'can-test-helpers.js', + 'resolutions': { + 'can-test-helpers': '1.1.4', + 'can-log': '1.0.2', + 'can-reflect': '1.18.0', + 'can-global': '1.0.1' + } + }, + { + 'name': 'can-observation-recorder', + 'version': '1.3.1', + '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.5' + } + }, + { + 'name': 'can-observation', + 'version': '4.2.0', + 'fileUrl': './node_modules/can-observation/package.json', + 'main': 'can-observation', + 'steal': { 'npmAlgorithm': 'flat' }, + 'resolutions': { + 'can-namespace': '1.0.0', + 'can-reflect': '1.18.0', + 'can-queues': '1.3.1', + 'can-observation-recorder': '1.3.1', + 'can-symbol': '1.6.5', + 'can-log': '1.0.2', + 'can-event-queue': '1.1.7', + 'can-observation': '4.2.0' + } + }, + { + 'name': 'can-attribute-encoder', + 'version': '1.1.4', + '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.2' + } + }, + { + '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': '1.0.0', + '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': '1.0.0', + 'steal-qunit': '2.0.0', + 'can-reflect': '1.18.0', + 'can-symbol': '1.6.5' + } + }, + { + 'name': 'can-set-legacy', + 'version': '1.0.1', + 'fileUrl': './node_modules/can-set-legacy/package.json', + 'main': 'can-set-legacy', + 'resolutions': { + 'can-query-logic': '1.2.2', + 'can-reflect': '1.18.0', + 'can-key': '1.2.1' + } + }, + { + 'name': 'jquery', + 'version': '3.5.1', + 'fileUrl': './node_modules/jquery/package.json', + 'main': 'dist/jquery.js', + 'resolutions': {} + }, + { + 'name': 'socket.io-client', + 'version': '2.3.0', + 'fileUrl': './node_modules/socket.io-client/package.json', + 'main': './lib/index', + 'resolutions': { + 'socket.io-client': '2.3.0', + 'socket.io-parser': '3.3.0', + 'debug': '4.1.1', + 'parseuri': '0.0.5', + 'engine.io-client': '3.4.1', + 'component-bind': '1.0.0', + 'indexof': '0.0.1', + 'backo2': '1.0.2', + 'to-array': '0.1.4', + 'parseqs': '0.0.5', + 'has-binary2': '1.0.3', + 'component-emitter': '1.2.1' + } + }, + { + 'name': '@feathersjs/feathers', + 'version': '3.3.1', + 'fileUrl': './node_modules/@feathersjs/feathers/package.json', + 'main': 'lib/index.js', + 'resolutions': { + '@feathersjs/feathers': '3.3.1', + '@feathersjs/commons': '4.5.3', + 'uberproto': '2.0.6', + 'debug': '4.1.1' + } + }, + { + 'name': '@feathersjs/socketio-client', + 'version': '1.2.1', + 'fileUrl': './node_modules/@feathersjs/socketio-client/package.json', + 'main': 'lib/index.js', + 'resolutions': { '@feathersjs/transport-commons': '4.5.3' } + }, + { + 'name': 'es6-promise-polyfill', + 'version': '1.2.0', + 'fileUrl': './node_modules/es6-promise-polyfill/package.json', + 'main': 'promise.js', + 'resolutions': {} + }, + { + 'name': 'object-assign', + 'version': '4.1.1', + 'fileUrl': './node_modules/object-assign/package.json', + 'resolutions': {} + }, + { + 'name': 'can-stache', + 'version': '4.17.21', + 'fileUrl': './node_modules/can-stache/package.json', + 'main': 'can-stache', + 'resolutions': { + 'can-view-parser': '4.1.3', + 'can-view-callbacks': '4.4.1', + 'can-stache': '4.17.21', + 'can-attribute-encoder': '1.1.4', + 'can-log': '1.0.2', + 'can-namespace': '1.0.0', + 'can-globals': '1.2.2', + 'can-assign': '1.3.3', + 'can-reflect': '1.18.0', + 'can-view-scope': '4.13.6', + 'can-observation-recorder': '1.3.1', + 'can-symbol': '1.6.5', + 'can-view-target': '4.1.6', + 'can-view-nodelist': '4.3.4', + 'can-stache-ast': '1.1.0', + 'can-import-module': '1.2.0', + 'can-view-live': '4.2.8', + 'can-dom-mutate': '1.3.11', + 'can-observation': '4.2.0', + 'can-fragment': '1.3.1', + 'can-define-lazy-value': '1.1.1', + 'can-stache-helpers': '1.2.0', + 'can-dom-data': '1.0.3', + 'can-stache-key': '1.4.3', + 'can-join-uris': '1.2.0', + 'can-simple-observable': '2.5.0' + } + }, + { + 'name': 'can-dom-data', + 'version': '1.0.3', + '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': 'can-view-callbacks', + 'version': '4.4.1', + 'fileUrl': './node_modules/can-view-callbacks/package.json', + 'main': 'can-view-callbacks', + 'resolutions': { + 'can-observation-recorder': '1.3.1', + 'can-log': '1.0.2', + 'can-globals': '1.2.2', + 'can-dom-mutate': '1.3.11', + 'can-namespace': '1.0.0', + 'can-view-nodelist': '4.3.4', + 'can-fragment': '1.3.1', + 'can-symbol': '1.6.5', + 'can-reflect': '1.18.0' + } + }, + { + 'name': 'can-observe', + 'version': '2.3.1', + 'fileUrl': './node_modules/can-observe/package.json', + 'main': 'can-observe.js', + 'resolutions': { + 'can-observe': '2.3.1', + 'can-reflect': '1.18.0', + 'can-observation-recorder': '1.3.1', + 'can-event-queue': '1.1.7', + 'can-globals': '1.2.2', + 'can-symbol': '1.6.5', + 'can-observation': '4.2.0', + 'can-simple-observable': '2.5.0', + 'can-queues': '1.3.1' + } + }, + { + 'name': 'can-data-types', + 'version': '1.2.1', + '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.18.0' } + }, + { + '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': 'qunit', + 'version': '2.10.0', + 'fileUrl': './node_modules/qunit/package.json', + 'main': 'qunit/qunit.js', + 'resolutions': { 'steal-qunit': '2.0.0' } + }, + { + 'name': 'can-string', + 'version': '1.1.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-child-nodes', + 'version': '1.2.1', + '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': 'can-single-reference', + 'version': '1.3.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.1' } + }, + { + 'name': 'can-cid', + 'version': '1.3.1', + 'fileUrl': './node_modules/can-cid/package.json', + 'main': 'can-cid', + 'resolutions': { + 'can-namespace': '1.0.0', + 'can-cid': '1.3.1' + } + }, + { + '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.18.0', + 'can-symbol': '1.6.5', + 'can-log': '1.0.2' + } + }, + { + 'name': 'socket.io-parser', + 'version': '3.3.0', + 'fileUrl': './node_modules/socket.io-parser/package.json', + 'resolutions': { + 'socket.io-parser': '3.3.0', + 'debug': '3.1.0', + 'isarray': '2.0.1', + 'component-emitter': '1.2.1' + } + }, + { + 'name': '@feathersjs/commons', + 'version': '4.5.3', + 'fileUrl': './node_modules/@feathersjs/commons/package.json', + 'main': 'lib/', + 'resolutions': { '@feathersjs/commons': '4.5.3' } + }, + { + 'name': 'uberproto', + 'version': '2.0.6', + 'fileUrl': './node_modules/uberproto/package.json', + 'main': 'lib/proto', + 'resolutions': {} + }, + { + 'name': '@feathersjs/transport-commons', + 'version': '4.5.3', + 'fileUrl': './node_modules/@feathersjs/transport-commons/package.json', + 'main': 'lib/', + 'resolutions': { + '@feathersjs/transport-commons': '4.5.3', + 'debug': '4.1.1', + '@feathersjs/errors': '4.5.3' + } + }, + { + 'name': 'kefir', + 'version': '3.8.6', + 'fileUrl': './node_modules/kefir/package.json', + 'main': 'dist/kefir.js', + 'resolutions': {} + }, + { + 'name': 'can-diff', + 'version': '1.5.0', + 'fileUrl': './node_modules/can-diff/package.json', + 'main': 'can-diff', + 'steal': { 'main': 'can-diff' }, + 'resolutions': { + 'can-reflect': '1.18.0', + 'can-diff': '1.5.0', + 'can-key-tree': '1.2.2', + 'can-symbol': '1.6.5', + 'can-queues': '1.3.1' + } + }, + { + '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.18.0', + 'validate.js': '0.11.1' + } + }, + { + 'name': 'can-vdom', + 'version': '4.4.2', + 'fileUrl': './node_modules/can-vdom/package.json', + 'main': 'can-vdom.js', + 'steal': { + 'map': { 'can-vdom@4.4.2#assert': 'chai/chai' }, + 'meta': { + 'chai/chai': { + 'format': 'global', + 'exports': 'chai.assert' + } + }, + 'plugins': ['chai'], + 'main': 'can-vdom' + }, + 'resolutions': { + 'can-simple-dom': '1.7.0', + 'can-vdom': '4.4.2', + 'can-view-parser': '4.1.3' + } + }, + { + '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.3' + } + }, + { + '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.2', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-global', + 'version': '1.0.1', + 'fileUrl': './node_modules/can-global/package.json', + 'main': 'dist/cjs/can-global', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'main': 'can-global' + }, + 'resolutions': {} + }, + { + 'name': 'can-attribute-observable', + 'version': '1.2.7', + 'fileUrl': './node_modules/can-attribute-observable/package.json', + 'main': 'can-attribute-observable', + 'resolutions': { + 'can-queues': '1.3.1', + 'can-attribute-observable': '1.2.7', + 'can-reflect': '1.18.0', + 'can-observation': '4.2.0', + 'can-reflect-dependencies': '1.1.2', + 'can-observation-recorder': '1.3.1', + 'can-simple-observable': '2.5.0', + 'can-assign': '1.3.3', + 'can-symbol': '1.6.5', + 'can-dom-events': '1.3.11', + 'can-event-dom-radiochange': '2.2.1', + 'can-globals': '1.2.2', + 'can-dom-data': '1.0.3', + 'can-dom-mutate': '1.3.11', + 'can-diff': '1.5.0' + } + }, + { + 'name': 'he', + 'version': '1.2.0', + 'fileUrl': './node_modules/he/package.json', + 'main': 'he.js', + 'resolutions': {} + }, + { + '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': 'can-memory-store', + 'version': '1.0.2', + 'fileUrl': './node_modules/can-memory-store/package.json', + 'main': 'can-memory-store', + 'resolutions': { + 'can-reflect': '1.18.0', + 'can-namespace': '1.0.0', + 'can-memory-store': '1.0.2' + } + }, + { + 'name': 'debug', + 'version': '4.1.1', + 'fileUrl': './node_modules/socket.io-client/node_modules/debug/package.json', + 'main': './src/index.js', + 'browser': './src/browser.js', + 'resolutions': { + 'debug': '4.1.1', + 'ms': '2.1.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.2' + } + }, + { + 'name': 'parseuri', + 'version': '0.0.5', + 'fileUrl': './node_modules/parseuri/package.json', + 'resolutions': {} + }, + { + 'name': 'debug', + 'version': '3.1.0', + 'fileUrl': './node_modules/socket.io-parser/node_modules/debug/package.json', + 'main': './src/index.js', + 'browser': './src/browser.js', + 'resolutions': { + 'debug': '3.1.0', + 'ms': '2.0.0' + } + }, + { + 'name': 'engine.io-client', + 'version': '3.4.1', + 'fileUrl': './node_modules/engine.io-client/package.json', + 'main': 'lib/index.js', + 'browser': { + 'ws': '@empty', + 'xmlhttprequest-ssl': 'engine.io-client#lib/xmlhttprequest', + 'engine.io-client#lib/globalThis': 'engine.io-client#lib/globalThis.browser' + }, + 'resolutions': { + 'engine.io-client': '3.4.1', + 'engine.io-parser': '2.2.0', + 'component-emitter': '1.2.1', + 'debug': '4.1.1', + 'indexof': '0.0.1', + 'parseuri': '0.0.5', + 'parseqs': '0.0.5', + 'has-cors': '1.1.0', + 'component-inherit': '0.0.3', + 'yeast': '0.1.2' + } + }, + { + 'name': 'component-bind', + 'version': '1.0.0', + 'fileUrl': './node_modules/component-bind/package.json', + 'resolutions': {} + }, + { + 'name': 'indexof', + 'version': '0.0.1', + 'fileUrl': './node_modules/indexof/package.json', + 'resolutions': {} + }, + { + 'name': 'backo2', + 'version': '1.0.2', + 'fileUrl': './node_modules/backo2/package.json', + 'resolutions': {} + }, + { + 'name': 'to-array', + 'version': '0.1.4', + 'fileUrl': './node_modules/to-array/package.json', + 'main': 'index', + 'resolutions': {} + }, + { + 'name': 'parseqs', + 'version': '0.0.5', + 'fileUrl': './node_modules/parseqs/package.json', + 'resolutions': {} + }, + { + 'name': 'has-binary2', + 'version': '1.0.3', + 'fileUrl': './node_modules/has-binary2/package.json', + 'resolutions': { 'isarray': '2.0.1' } + }, + { + 'name': '@feathersjs/errors', + 'version': '4.5.3', + 'fileUrl': './node_modules/@feathersjs/errors/package.json', + 'main': 'lib/index', + 'resolutions': { 'debug': '4.1.1' } + }, + { + 'name': 'isarray', + 'version': '2.0.1', + 'fileUrl': './node_modules/socket.io-parser/node_modules/isarray/package.json', + 'main': 'index.js', + 'resolutions': {} + }, + { + 'name': 'component-emitter', + 'version': '1.2.1', + 'fileUrl': './node_modules/socket.io-parser/node_modules/component-emitter/package.json', + 'main': 'index.js', + 'resolutions': {} + }, + { + 'name': 'ms', + 'version': '2.1.2', + 'fileUrl': './node_modules/socket.io-client/node_modules/ms/package.json', + 'main': './index', + 'resolutions': {} + }, + { + 'name': 'ms', + 'version': '2.0.0', + 'fileUrl': './node_modules/ms/package.json', + 'main': './index', + 'resolutions': {} + }, + { + 'name': 'engine.io-parser', + 'version': '2.2.0', + 'fileUrl': './node_modules/engine.io-parser/package.json', + 'main': 'lib/index.js', + 'browser': './lib/browser.js', + 'resolutions': { + 'engine.io-parser': '2.2.0', + 'has-binary2': '1.0.3', + 'arraybuffer.slice': '0.0.7', + 'after': '0.8.2', + 'base64-arraybuffer': '0.1.5', + 'blob': '0.0.5' + } + }, + { + 'name': 'arraybuffer.slice', + 'version': '0.0.7', + '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.5', + 'fileUrl': './node_modules/blob/package.json', + 'resolutions': {} + }, + { + 'name': 'has-cors', + 'version': '1.1.0', + 'fileUrl': './node_modules/has-cors/package.json', + 'main': 'index.js', + 'resolutions': {} + }, + { + 'name': 'component-inherit', + 'version': '0.0.3', + 'fileUrl': './node_modules/component-inherit/package.json', + 'resolutions': {} + }, + { + 'name': 'yeast', + 'version': '0.1.2', + 'fileUrl': './node_modules/yeast/package.json', + 'main': 'index.js', + 'resolutions': {} + } + ], { 'npmParentMap': { '@feathersjs/feathers@3.3.1#lib/hooks': '@feathersjs/feathers@3.3.1#lib/hooks/index' } })); +}); +/*steal-qunit@2.0.0#add-dom*/ +define('steal-qunit@2.0.0#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); + } +}); +/*qunit@2.10.0#qunit/qunit*/ +define('qunit@2.10.0#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 2.10.0\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: 2020-05-02T22:51Z\n */\n(function (global$1) {\n \'use strict\';\n\n global$1 = global$1 && global$1.hasOwnProperty(\'default\') ? global$1[\'default\'] : global$1;\n\n var window$1 = global$1.window;\n var self$1 = global$1.self;\n var console = global$1.console;\n var setTimeout$1 = global$1.setTimeout;\n var clearTimeout = global$1.clearTimeout;\n\n var document$1 = window$1 && window$1.document;\n var navigator = window$1 && window$1.navigator;\n\n var localSessionStorage = function () {\n \tvar x = "qunit-test-string";\n \ttry {\n \t\tglobal$1.sessionStorage.setItem(x, x);\n \t\tglobal$1.sessionStorage.removeItem(x);\n \t\treturn global$1.sessionStorage;\n \t} catch (e) {\n \t\treturn undefined;\n \t}\n }();\n\n /**\n * Returns a function that proxies to the given method name on the globals\n * console object. The proxy will also detect if the console doesn\'t exist and\n * will appropriately no-op. This allows support for IE9, which doesn\'t have a\n * console if the developer tools are not open.\n */\n function consoleProxy(method) {\n \treturn function () {\n \t\tif (console) {\n \t\t\tconsole[method].apply(console, arguments);\n \t\t}\n \t};\n }\n\n var Logger = {\n \twarn: consoleProxy("warn")\n };\n\n var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {\n return typeof obj;\n } : function (obj) {\n return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;\n };\n\n\n\n\n\n\n\n\n\n\n\n var classCallCheck = function (instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError("Cannot call a class as a function");\n }\n };\n\n var createClass = function () {\n function defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if ("value" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n }\n\n return function (Constructor, protoProps, staticProps) {\n if (protoProps) defineProperties(Constructor.prototype, protoProps);\n if (staticProps) defineProperties(Constructor, staticProps);\n return Constructor;\n };\n }();\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n var toConsumableArray = function (arr) {\n if (Array.isArray(arr)) {\n for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];\n\n return arr2;\n } else {\n return Array.from(arr);\n }\n };\n\n var toString = Object.prototype.toString;\n var hasOwn = Object.prototype.hasOwnProperty;\n var now = Date.now || function () {\n \treturn new Date().getTime();\n };\n\n var hasPerformanceApi = detectPerformanceApi();\n var performance = hasPerformanceApi ? window$1.performance : undefined;\n var performanceNow = hasPerformanceApi ? performance.now.bind(performance) : now;\n\n function detectPerformanceApi() {\n \treturn window$1 && typeof window$1.performance !== "undefined" && typeof window$1.performance.mark === "function" && typeof window$1.performance.measure === "function";\n }\n\n function measure(comment, startMark, endMark) {\n\n \t// `performance.measure` may fail if the mark could not be found.\n \t// reasons a specific mark could not be found include: outside code invoking `performance.clearMarks()`\n \ttry {\n \t\tperformance.measure(comment, startMark, endMark);\n \t} catch (ex) {\n \t\tLogger.warn("performance.measure could not be executed because of ", ex.message);\n \t}\n }\n\n var defined = {\n \tdocument: window$1 && window$1.document !== undefined,\n \tsetTimeout: setTimeout$1 !== undefined\n };\n\n // Returns a new Array with the elements that are in a but not in b\n function diff(a, b) {\n \tvar i,\n \t j,\n \t result = 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 /**\n * Determines whether an element exists in a given array or not.\n *\n * @method inArray\n * @param {Any} elem\n * @param {Array} array\n * @return {Boolean}\n */\n function inArray(elem, array) {\n \treturn array.indexOf(elem) !== -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 */\n function objectValues(obj) {\n \tvar key,\n \t val,\n \t vals = 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\n function extend(a, b, undefOnly) {\n \tfor (var prop in b) {\n \t\tif (hasOwn.call(b, prop)) {\n \t\t\tif (b[prop] === undefined) {\n \t\t\t\tdelete a[prop];\n \t\t\t} else if (!(undefOnly && typeof a[prop] !== "undefined")) {\n \t\t\t\ta[prop] = b[prop];\n \t\t\t}\n \t\t}\n \t}\n\n \treturn a;\n }\n\n function 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 type = 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\tdefault:\n \t\t\treturn typeof obj === "undefined" ? "undefined" : _typeof(obj);\n \t}\n }\n\n // Safe object type checking\n function is(type, obj) {\n \treturn objectType(obj) === type;\n }\n\n // Based on Java\'s String.hashCode, a simple but not\n // rigorously collision resistant hashing function\n function generateHash(module, testName) {\n \tvar str = module + "\\x1C" + testName;\n \tvar hash = 0;\n\n \tfor (var i = 0; i < str.length; 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 \tvar hex = (0x100000000 + hash).toString(16);\n \tif (hex.length < 8) {\n \t\thex = "0000000" + hex;\n \t}\n\n \treturn hex.slice(-8);\n }\n\n // Test for equality any JavaScript type.\n // Authors: Philippe Rathé , David Chan \n var equiv = (function () {\n\n \t// Value pairs queued for comparison. Used for breadth-first processing order, recursion\n \t// detection and avoiding repeated comparison (see below for details).\n \t// Elements are { a: val, b: val }.\n \tvar pairs = [];\n\n \tvar getProto = Object.getPrototypeOf || function (obj) {\n \t\treturn obj.__proto__;\n \t};\n\n \tfunction useStrictEquality(a, b) {\n\n \t\t// This only gets called if a and b are not strict equal, and is used to compare on\n \t\t// the primitive values inside object wrappers. For example:\n \t\t// `var i = 1;`\n \t\t// `var j = new Number(1);`\n \t\t// Neither a nor b can be null, as a !== b and they have the same type.\n \t\tif ((typeof a === "undefined" ? "undefined" : _typeof(a)) === "object") {\n \t\t\ta = a.valueOf();\n \t\t}\n \t\tif ((typeof b === "undefined" ? "undefined" : _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 || 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 \tfunction isContainer(val) {\n \t\treturn ["object", "array", "map", "set"].indexOf(objectType(val)) !== -1;\n \t}\n\n \tfunction breadthFirstCompareChild(a, b) {\n\n \t\t// If a is a container not reference-equal to b, postpone the comparison to the\n \t\t// end of the pairs queue -- unless (a, b) has been seen before, in which case skip\n \t\t// over the pair.\n \t\tif (a === b) {\n \t\t\treturn true;\n \t\t}\n \t\tif (!isContainer(a)) {\n \t\t\treturn typeEquiv(a, b);\n \t\t}\n \t\tif (pairs.every(function (pair) {\n \t\t\treturn pair.a !== a || pair.b !== b;\n \t\t})) {\n\n \t\t\t// Not yet started comparing this pair\n \t\t\tpairs.push({ a: a, b: b });\n \t\t}\n \t\treturn true;\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 nan() {\n \t\t\treturn true;\n \t\t},\n\n \t\t"regexp": function regexp(a, b) {\n \t\t\treturn a.source === b.source &&\n\n \t\t\t// Include flags in the comparison\n \t\t\tgetRegExpFlags(a) === getRegExpFlags(b);\n \t\t},\n\n \t\t// abort (identical references / instance methods were skipped earlier)\n \t\t"function": function _function() {\n \t\t\treturn false;\n \t\t},\n\n \t\t"array": function array(a, b) {\n \t\t\tvar i, len;\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\tfor (i = 0; i < len; i++) {\n\n \t\t\t\t// Compare non-containers; queue non-reference-equal containers\n \t\t\t\tif (!breadthFirstCompareChild(a[i], b[i])) {\n \t\t\t\t\treturn false;\n \t\t\t\t}\n \t\t\t}\n \t\t\treturn true;\n \t\t},\n\n \t\t// Define sets a and b to be equivalent if for each element aVal in a, there\n \t\t// is some element bVal in b such that aVal and bVal are equivalent. Element\n \t\t// repetitions are not counted, so these are equivalent:\n \t\t// a = new Set( [ {}, [], [] ] );\n \t\t// b = new Set( [ {}, {}, [] ] );\n \t\t"set": function set$$1(a, b) {\n \t\t\tvar innerEq,\n \t\t\t outerEq = true;\n\n \t\t\tif (a.size !== b.size) {\n\n \t\t\t\t// This optimization has certain quirks because of the lack of\n \t\t\t\t// repetition counting. For instance, adding the same\n \t\t\t\t// (reference-identical) element to two equivalent sets can\n \t\t\t\t// make them non-equivalent.\n \t\t\t\treturn false;\n \t\t\t}\n\n \t\t\ta.forEach(function (aVal) {\n\n \t\t\t\t// Short-circuit if the result is already known. (Using for...of\n \t\t\t\t// with a break clause would be cleaner here, but it would cause\n \t\t\t\t// a syntax error on older Javascript implementations even if\n \t\t\t\t// Set is unused)\n \t\t\t\tif (!outerEq) {\n \t\t\t\t\treturn;\n \t\t\t\t}\n\n \t\t\t\tinnerEq = false;\n\n \t\t\t\tb.forEach(function (bVal) {\n \t\t\t\t\tvar parentPairs;\n\n \t\t\t\t\t// Likewise, short-circuit if the result is already known\n \t\t\t\t\tif (innerEq) {\n \t\t\t\t\t\treturn;\n \t\t\t\t\t}\n\n \t\t\t\t\t// Swap out the global pairs list, as the nested call to\n \t\t\t\t\t// innerEquiv will clobber its contents\n \t\t\t\t\tparentPairs = pairs;\n \t\t\t\t\tif (innerEquiv(bVal, aVal)) {\n \t\t\t\t\t\tinnerEq = true;\n \t\t\t\t\t}\n\n \t\t\t\t\t// Replace the global pairs list\n \t\t\t\t\tpairs = parentPairs;\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// Define maps a and b to be equivalent if for each key-value pair (aKey, aVal)\n \t\t// in a, there is some key-value pair (bKey, bVal) in b such that\n \t\t// [ aKey, aVal ] and [ bKey, bVal ] are equivalent. Key repetitions are not\n \t\t// counted, so these are equivalent:\n \t\t// a = new Map( [ [ {}, 1 ], [ {}, 1 ], [ [], 1 ] ] );\n \t\t// b = new Map( [ [ {}, 1 ], [ [], 1 ], [ [], 1 ] ] );\n \t\t"map": function map(a, b) {\n \t\t\tvar innerEq,\n \t\t\t outerEq = true;\n\n \t\t\tif (a.size !== b.size) {\n\n \t\t\t\t// This optimization has certain quirks because of the lack of\n \t\t\t\t// repetition counting. For instance, adding the same\n \t\t\t\t// (reference-identical) key-value pair to two equivalent maps\n \t\t\t\t// can make them non-equivalent.\n \t\t\t\treturn false;\n \t\t\t}\n\n \t\t\ta.forEach(function (aVal, aKey) {\n\n \t\t\t\t// Short-circuit if the result is already known. (Using for...of\n \t\t\t\t// with a break clause would be cleaner here, but it would cause\n \t\t\t\t// a syntax error on older Javascript implementations even if\n \t\t\t\t// Map is unused)\n \t\t\t\tif (!outerEq) {\n \t\t\t\t\treturn;\n \t\t\t\t}\n\n \t\t\t\tinnerEq = false;\n\n \t\t\t\tb.forEach(function (bVal, bKey) {\n \t\t\t\t\tvar parentPairs;\n\n \t\t\t\t\t// Likewise, short-circuit if the result is already known\n \t\t\t\t\tif (innerEq) {\n \t\t\t\t\t\treturn;\n \t\t\t\t\t}\n\n \t\t\t\t\t// Swap out the global pairs list, as the nested call to\n \t\t\t\t\t// innerEquiv will clobber its contents\n \t\t\t\t\tparentPairs = pairs;\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\n \t\t\t\t\t// Replace the global pairs list\n \t\t\t\t\tpairs = parentPairs;\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 object(a, b) {\n \t\t\tvar i,\n \t\t\t aProperties = [],\n \t\t\t 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// Be strict: don\'t ensure hasOwnProperty and go deep\n \t\t\tfor (i in a) {\n\n \t\t\t\t// Collect a\'s properties\n \t\t\t\taProperties.push(i);\n\n \t\t\t\t// Skip OOP methods that look the same\n \t\t\t\tif (a.constructor !== Object && typeof a.constructor !== "undefined" && typeof a[i] === "function" && typeof b[i] === "function" && a[i].toString() === b[i].toString()) {\n \t\t\t\t\tcontinue;\n \t\t\t\t}\n\n \t\t\t\t// Compare non-containers; queue non-reference-equal containers\n \t\t\t\tif (!breadthFirstCompareChild(a[i], b[i])) {\n \t\t\t\t\treturn false;\n \t\t\t\t}\n \t\t\t}\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 typeEquiv(aProperties.sort(), bProperties.sort());\n \t\t}\n \t};\n\n \tfunction typeEquiv(a, b) {\n \t\tvar type = objectType(a);\n\n \t\t// Callbacks for containers will append to the pairs queue to achieve breadth-first\n \t\t// search order. The pairs queue is also used to avoid reprocessing any pair of\n \t\t// containers that are reference-equal to a previously visited pair (a special case\n \t\t// this being recursion detection).\n \t\t//\n \t\t// Because of this approach, once typeEquiv returns a false value, it should not be\n \t\t// called again without clearing the pair queue else it may wrongly report a visited\n \t\t// pair as being equivalent.\n \t\treturn objectType(b) === type && callbacks[type](a, b);\n \t}\n\n \tfunction innerEquiv(a, b) {\n \t\tvar i, pair;\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// Clear the global pair queue and add the top-level values being compared\n \t\tpairs = [{ a: a, b: b }];\n\n \t\tfor (i = 0; i < pairs.length; i++) {\n \t\t\tpair = pairs[i];\n\n \t\t\t// Perform type-specific comparison on any pairs that are not strictly\n \t\t\t// equal. For container types, that comparison will postpone comparison\n \t\t\t// of any sub-container pair to the end of the pair queue. This gives\n \t\t\t// breadth-first search order. It also avoids the reprocessing of\n \t\t\t// reference-equal siblings, cousins etc, which can have a significant speed\n \t\t\t// impact when comparing a container of small objects each of which has a\n \t\t\t// reference to the same (singleton) large object.\n \t\t\tif (pair.a !== pair.b && !typeEquiv(pair.a, pair.b)) {\n \t\t\t\treturn false;\n \t\t\t}\n \t\t}\n\n \t\t// ...across all consecutive argument pairs\n \t\treturn arguments.length === 2 || innerEquiv.apply(this, [].slice.call(arguments, 1));\n \t}\n\n \treturn function () {\n \t\tvar result = innerEquiv.apply(undefined, arguments);\n\n \t\t// Release any retained objects\n \t\tpairs.length = 0;\n \t\treturn result;\n \t};\n })();\n\n /**\n * Config object: Maintain internal state\n * Later exposed as QUnit.config\n * `config` initialized at top of scope\n */\n var 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// The first unnamed module\n \tcurrentModule: {\n \t\tname: "",\n \t\ttests: [],\n \t\tchildModules: [],\n \t\ttestsRun: 0,\n \t\tunskippedTestsRun: 0,\n \t\thooks: {\n \t\t\tbefore: [],\n \t\t\tbeforeEach: [],\n \t\t\tafterEach: [],\n \t\t\tafter: []\n \t\t}\n \t},\n\n \tcallbacks: {},\n\n \t// The storage module to use for reordering tests\n \tstorage: localSessionStorage\n };\n\n // take a predefined QUnit.config and extend the defaults\n var globalConfig = window$1 && window$1.QUnit && window$1.QUnit.config;\n\n // only extend the global config if there is no QUnit overload\n if (window$1 && window$1.QUnit && !window$1.QUnit.version) {\n \textend(config, globalConfig);\n }\n\n // Push a loose unnamed module to the modules collection\n config.modules.push(config.currentModule);\n\n // Based on jsDump by Ariel Flesler\n // http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html\n var 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 base = dump.indent(),\n \t\t inner = 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 ret = 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 \tfunction isArray(obj) {\n \t\treturn (\n\n \t\t\t//Native Arrays\n \t\t\ttoString.call(obj) === "[object Array]" ||\n\n \t\t\t// NodeList objects\n \t\t\ttypeof obj.length === "number" && obj.item !== undefined && (obj.length ? obj.item(0) === obj[0] : obj.item(0) === null && obj[0] === undefined)\n \t\t);\n \t}\n\n \tvar reName = /^function (\\w+)/,\n \t dump = {\n\n \t\t// The objType is used mostly internally, you can fix a (custom) type in advance\n \t\tparse: function parse(obj, objType, stack) {\n \t\t\tstack = stack || [];\n \t\t\tvar res,\n \t\t\t parser,\n \t\t\t parserType,\n \t\t\t objIndex = stack.indexOf(obj);\n\n \t\t\tif (objIndex !== -1) {\n \t\t\t\treturn "recursion(" + (objIndex - stack.length) + ")";\n \t\t\t}\n\n \t\t\tobjType = objType || this.typeOf(obj);\n \t\t\tparser = this.parsers[objType];\n \t\t\tparserType = typeof parser === "undefined" ? "undefined" : _typeof(parser);\n\n \t\t\tif (parserType === "function") {\n \t\t\t\tstack.push(obj);\n \t\t\t\tres = parser.call(this, obj, stack);\n \t\t\t\tstack.pop();\n \t\t\t\treturn res;\n \t\t\t}\n \t\t\treturn parserType === "string" ? parser : this.parsers.error;\n \t\t},\n \t\ttypeOf: function typeOf(obj) {\n \t\t\tvar type;\n\n \t\t\tif (obj === null) {\n \t\t\t\ttype = "null";\n \t\t\t} else if (typeof obj === "undefined") {\n \t\t\t\ttype = "undefined";\n \t\t\t} else if (is("regexp", obj)) {\n \t\t\t\ttype = "regexp";\n \t\t\t} else if (is("date", obj)) {\n \t\t\t\ttype = "date";\n \t\t\t} else if (is("function", obj)) {\n \t\t\t\ttype = "function";\n \t\t\t} else if (obj.setInterval !== undefined && obj.document !== undefined && obj.nodeType === undefined) {\n \t\t\t\ttype = "window";\n \t\t\t} else if (obj.nodeType === 9) {\n \t\t\t\ttype = "document";\n \t\t\t} else if (obj.nodeType) {\n \t\t\t\ttype = "node";\n \t\t\t} else if (isArray(obj)) {\n \t\t\t\ttype = "array";\n \t\t\t} else if (obj.constructor === Error.prototype.constructor) {\n \t\t\t\ttype = "error";\n \t\t\t} else {\n \t\t\t\ttype = typeof obj === "undefined" ? "undefined" : _typeof(obj);\n \t\t\t}\n \t\t\treturn type;\n \t\t},\n\n \t\tseparator: function separator() {\n \t\t\tif (this.multiline) {\n \t\t\t\treturn this.HTML ? "
" : "\\n";\n \t\t\t} else {\n \t\t\t\treturn this.HTML ? " " : " ";\n \t\t\t}\n \t\t},\n\n \t\t// Extra can be a number, shortcut for increasing-calling-decreasing\n \t\tindent: function indent(extra) {\n \t\t\tif (!this.multiline) {\n \t\t\t\treturn "";\n \t\t\t}\n \t\t\tvar chr = this.indentChar;\n \t\t\tif (this.HTML) {\n \t\t\t\tchr = chr.replace(/\\t/g, " ").replace(/ /g, " ");\n \t\t\t}\n \t\t\treturn new Array(this.depth + (extra || 0)).join(chr);\n \t\t},\n \t\tup: function up(a) {\n \t\t\tthis.depth += a || 1;\n \t\t},\n \t\tdown: function down(a) {\n \t\t\tthis.depth -= a || 1;\n \t\t},\n \t\tsetParser: function setParser(name, parser) {\n \t\t\tthis.parsers[name] = parser;\n \t\t},\n\n \t\t// The next 3 are exposed so you can use them\n \t\tquote: quote,\n \t\tliteral: literal,\n \t\tjoin: join,\n \t\tdepth: 1,\n \t\tmaxDepth: config.maxDepth,\n\n \t\t// This is the list of parsers, to modify them, use dump.setParser\n \t\tparsers: {\n \t\t\twindow: "[Window]",\n \t\t\tdocument: "[Document]",\n \t\t\terror: function error(_error) {\n \t\t\t\treturn "Error(\\"" + _error.message + "\\")";\n \t\t\t},\n \t\t\tunknown: "[Unknown]",\n \t\t\t"null": "null",\n \t\t\t"undefined": "undefined",\n \t\t\t"function": function _function(fn) {\n \t\t\t\tvar ret = "function",\n\n\n \t\t\t\t// Functions never have name in IE\n \t\t\t\tname = "name" in fn ? fn.name : (reName.exec(fn) || [])[1];\n\n \t\t\t\tif (name) {\n \t\t\t\t\tret += " " + name;\n \t\t\t\t}\n \t\t\t\tret += "(";\n\n \t\t\t\tret = [ret, dump.parse(fn, "functionArgs"), "){"].join("");\n \t\t\t\treturn join(ret, dump.parse(fn, "functionCode"), "}");\n \t\t\t},\n \t\t\tarray: array,\n \t\t\tnodelist: array,\n \t\t\t"arguments": array,\n \t\t\tobject: function object(map, stack) {\n \t\t\t\tvar keys,\n \t\t\t\t key,\n \t\t\t\t val,\n \t\t\t\t i,\n \t\t\t\t nonEnumerableProperties,\n \t\t\t\t ret = [];\n\n \t\t\t\tif (dump.maxDepth && dump.depth > dump.maxDepth) {\n \t\t\t\t\treturn "[object Object]";\n \t\t\t\t}\n\n \t\t\t\tdump.up();\n \t\t\t\tkeys = [];\n \t\t\t\tfor (key in map) {\n \t\t\t\t\tkeys.push(key);\n \t\t\t\t}\n\n \t\t\t\t// Some properties are not always enumerable on Error objects.\n \t\t\t\tnonEnumerableProperties = ["message", "name"];\n \t\t\t\tfor (i in nonEnumerableProperties) {\n \t\t\t\t\tkey = nonEnumerableProperties[i];\n \t\t\t\t\tif (key in map && !inArray(key, keys)) {\n \t\t\t\t\t\tkeys.push(key);\n \t\t\t\t\t}\n \t\t\t\t}\n \t\t\t\tkeys.sort();\n \t\t\t\tfor (i = 0; i < keys.length; i++) {\n \t\t\t\t\tkey = keys[i];\n \t\t\t\t\tval = map[key];\n \t\t\t\t\tret.push(dump.parse(key, "key") + ": " + dump.parse(val, undefined, stack));\n \t\t\t\t}\n \t\t\t\tdump.down();\n \t\t\t\treturn join("{", ret, "}");\n \t\t\t},\n \t\t\tnode: function node(_node) {\n \t\t\t\tvar len,\n \t\t\t\t i,\n \t\t\t\t val,\n \t\t\t\t open = dump.HTML ? "<" : "<",\n \t\t\t\t close = dump.HTML ? ">" : ">",\n \t\t\t\t tag = _node.nodeName.toLowerCase(),\n \t\t\t\t ret = open + tag,\n \t\t\t\t attrs = _node.attributes;\n\n \t\t\t\tif (attrs) {\n \t\t\t\t\tfor (i = 0, len = attrs.length; i < len; i++) {\n \t\t\t\t\t\tval = attrs[i].nodeValue;\n\n \t\t\t\t\t\t// IE6 includes all attributes in .attributes, even ones not explicitly\n \t\t\t\t\t\t// set. Those have values like undefined, null, 0, false, "" or\n \t\t\t\t\t\t// "inherit".\n \t\t\t\t\t\tif (val && val !== "inherit") {\n \t\t\t\t\t\t\tret += " " + attrs[i].nodeName + "=" + dump.parse(val, "attribute");\n \t\t\t\t\t\t}\n \t\t\t\t\t}\n \t\t\t\t}\n \t\t\t\tret += close;\n\n \t\t\t\t// Show content of TextNode or CDATASection\n \t\t\t\tif (_node.nodeType === 3 || _node.nodeType === 4) {\n \t\t\t\t\tret += _node.nodeValue;\n \t\t\t\t}\n\n \t\t\t\treturn ret + open + "/" + tag + close;\n \t\t\t},\n\n \t\t\t// Function calls it internally, it\'s the arguments part of the function\n \t\t\tfunctionArgs: function functionArgs(fn) {\n \t\t\t\tvar args,\n \t\t\t\t l = fn.length;\n\n \t\t\t\tif (!l) {\n \t\t\t\t\treturn "";\n \t\t\t\t}\n\n \t\t\t\targs = new Array(l);\n \t\t\t\twhile (l--) {\n\n \t\t\t\t\t// 97 is \'a\'\n \t\t\t\t\targs[l] = String.fromCharCode(97 + l);\n \t\t\t\t}\n \t\t\t\treturn " " + args.join(", ") + " ";\n \t\t\t},\n\n \t\t\t// Object calls it internally, the key part of an item in a map\n \t\t\tkey: quote,\n\n \t\t\t// Function calls it internally, it\'s the content of the function\n \t\t\tfunctionCode: "[code]",\n\n \t\t\t// Node calls it internally, it\'s a html attribute value\n \t\t\tattribute: quote,\n \t\t\tstring: quote,\n \t\t\tdate: quote,\n \t\t\tregexp: literal,\n \t\t\tnumber: literal,\n \t\t\t"boolean": literal,\n \t\t\tsymbol: function symbol(sym) {\n \t\t\t\treturn sym.toString();\n \t\t\t}\n \t\t},\n\n \t\t// If true, entities are escaped ( <, >, \\t, space and \\n )\n \t\tHTML: false,\n\n \t\t// Indentation unit\n \t\tindentChar: " ",\n\n \t\t// If true, items in a collection, are separated by a \\n, else just a space.\n \t\tmultiline: true\n \t};\n\n \treturn dump;\n })();\n\n var SuiteReport = function () {\n \tfunction SuiteReport(name, parentSuite) {\n \t\tclassCallCheck(this, SuiteReport);\n\n \t\tthis.name = name;\n \t\tthis.fullName = parentSuite ? parentSuite.fullName.concat(name) : [];\n\n \t\tthis.tests = [];\n \t\tthis.childSuites = [];\n\n \t\tif (parentSuite) {\n \t\t\tparentSuite.pushChildSuite(this);\n \t\t}\n \t}\n\n \tcreateClass(SuiteReport, [{\n \t\tkey: "start",\n \t\tvalue: function start(recordTime) {\n \t\t\tif (recordTime) {\n \t\t\t\tthis._startTime = performanceNow();\n\n \t\t\t\tif (performance) {\n \t\t\t\t\tvar suiteLevel = this.fullName.length;\n \t\t\t\t\tperformance.mark("qunit_suite_" + suiteLevel + "_start");\n \t\t\t\t}\n \t\t\t}\n\n \t\t\treturn {\n \t\t\t\tname: this.name,\n \t\t\t\tfullName: this.fullName.slice(),\n \t\t\t\ttests: this.tests.map(function (test) {\n \t\t\t\t\treturn test.start();\n \t\t\t\t}),\n \t\t\t\tchildSuites: this.childSuites.map(function (suite) {\n \t\t\t\t\treturn suite.start();\n \t\t\t\t}),\n \t\t\t\ttestCounts: {\n \t\t\t\t\ttotal: this.getTestCounts().total\n \t\t\t\t}\n \t\t\t};\n \t\t}\n \t}, {\n \t\tkey: "end",\n \t\tvalue: function end(recordTime) {\n \t\t\tif (recordTime) {\n \t\t\t\tthis._endTime = performanceNow();\n\n \t\t\t\tif (performance) {\n \t\t\t\t\tvar suiteLevel = this.fullName.length;\n \t\t\t\t\tperformance.mark("qunit_suite_" + suiteLevel + "_end");\n\n \t\t\t\t\tvar suiteName = this.fullName.join(" \u2013 ");\n\n \t\t\t\t\tmeasure(suiteLevel === 0 ? "QUnit Test Run" : "QUnit Test Suite: " + suiteName, "qunit_suite_" + suiteLevel + "_start", "qunit_suite_" + suiteLevel + "_end");\n \t\t\t\t}\n \t\t\t}\n\n \t\t\treturn {\n \t\t\t\tname: this.name,\n \t\t\t\tfullName: this.fullName.slice(),\n \t\t\t\ttests: this.tests.map(function (test) {\n \t\t\t\t\treturn test.end();\n \t\t\t\t}),\n \t\t\t\tchildSuites: this.childSuites.map(function (suite) {\n \t\t\t\t\treturn suite.end();\n \t\t\t\t}),\n \t\t\t\ttestCounts: this.getTestCounts(),\n \t\t\t\truntime: this.getRuntime(),\n \t\t\t\tstatus: this.getStatus()\n \t\t\t};\n \t\t}\n \t}, {\n \t\tkey: "pushChildSuite",\n \t\tvalue: function pushChildSuite(suite) {\n \t\t\tthis.childSuites.push(suite);\n \t\t}\n \t}, {\n \t\tkey: "pushTest",\n \t\tvalue: function pushTest(test) {\n \t\t\tthis.tests.push(test);\n \t\t}\n \t}, {\n \t\tkey: "getRuntime",\n \t\tvalue: function getRuntime() {\n \t\t\treturn this._endTime - this._startTime;\n \t\t}\n \t}, {\n \t\tkey: "getTestCounts",\n \t\tvalue: function getTestCounts() {\n \t\t\tvar counts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { passed: 0, failed: 0, skipped: 0, todo: 0, total: 0 };\n\n \t\t\tcounts = this.tests.reduce(function (counts, test) {\n \t\t\t\tif (test.valid) {\n \t\t\t\t\tcounts[test.getStatus()]++;\n \t\t\t\t\tcounts.total++;\n \t\t\t\t}\n\n \t\t\t\treturn counts;\n \t\t\t}, counts);\n\n \t\t\treturn this.childSuites.reduce(function (counts, suite) {\n \t\t\t\treturn suite.getTestCounts(counts);\n \t\t\t}, counts);\n \t\t}\n \t}, {\n \t\tkey: "getStatus",\n \t\tvalue: function getStatus() {\n \t\t\tvar _getTestCounts = this.getTestCounts(),\n \t\t\t total = _getTestCounts.total,\n \t\t\t failed = _getTestCounts.failed,\n \t\t\t skipped = _getTestCounts.skipped,\n \t\t\t todo = _getTestCounts.todo;\n\n \t\t\tif (failed) {\n \t\t\t\treturn "failed";\n \t\t\t} else {\n \t\t\t\tif (skipped === total) {\n \t\t\t\t\treturn "skipped";\n \t\t\t\t} else if (todo === total) {\n \t\t\t\t\treturn "todo";\n \t\t\t\t} else {\n \t\t\t\t\treturn "passed";\n \t\t\t\t}\n \t\t\t}\n \t\t}\n \t}]);\n \treturn SuiteReport;\n }();\n\n var focused = false;\n\n var moduleStack = [];\n\n function isParentModuleInQueue() {\n \tvar modulesInQueue = config.modules.map(function (module) {\n \t\treturn module.moduleId;\n \t});\n \treturn moduleStack.some(function (module) {\n \t\treturn modulesInQueue.includes(module.moduleId);\n \t});\n }\n\n function createModule(name, testEnvironment, modifiers) {\n \tvar parentModule = moduleStack.length ? moduleStack.slice(-1)[0] : null;\n \tvar moduleName = parentModule !== null ? [parentModule.name, name].join(" > ") : name;\n \tvar parentSuite = parentModule ? parentModule.suiteReport : globalSuite;\n\n \tvar skip = parentModule !== null && parentModule.skip || modifiers.skip;\n \tvar todo = parentModule !== null && parentModule.todo || modifiers.todo;\n\n \tvar module = {\n \t\tname: moduleName,\n \t\tparentModule: parentModule,\n \t\ttests: [],\n \t\tmoduleId: generateHash(moduleName),\n \t\ttestsRun: 0,\n \t\tunskippedTestsRun: 0,\n \t\tchildModules: [],\n \t\tsuiteReport: new SuiteReport(name, parentSuite),\n\n \t\t// Pass along `skip` and `todo` properties from parent module, in case\n \t\t// there is one, to childs. And use own otherwise.\n \t\t// This property will be used to mark own tests and tests of child suites\n \t\t// as either `skipped` or `todo`.\n \t\tskip: skip,\n \t\ttodo: skip ? false : todo\n \t};\n\n \tvar env = {};\n \tif (parentModule) {\n \t\tparentModule.childModules.push(module);\n \t\textend(env, parentModule.testEnvironment);\n \t}\n \textend(env, testEnvironment);\n \tmodule.testEnvironment = env;\n\n \tconfig.modules.push(module);\n \treturn module;\n }\n\n function processModule(name, options, executeNow) {\n \tvar modifiers = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};\n\n \tif (objectType(options) === "function") {\n \t\texecuteNow = options;\n \t\toptions = undefined;\n \t}\n\n \tvar module = createModule(name, options, modifiers);\n\n \t// Move any hooks to a \'hooks\' object\n \tvar testEnvironment = module.testEnvironment;\n \tvar hooks = module.hooks = {};\n\n \tsetHookFromEnvironment(hooks, testEnvironment, "before");\n \tsetHookFromEnvironment(hooks, testEnvironment, "beforeEach");\n \tsetHookFromEnvironment(hooks, testEnvironment, "afterEach");\n \tsetHookFromEnvironment(hooks, testEnvironment, "after");\n\n \tvar moduleFns = {\n \t\tbefore: setHookFunction(module, "before"),\n \t\tbeforeEach: setHookFunction(module, "beforeEach"),\n \t\tafterEach: setHookFunction(module, "afterEach"),\n \t\tafter: setHookFunction(module, "after")\n \t};\n\n \tvar currentModule = config.currentModule;\n \tif (objectType(executeNow) === "function") {\n \t\tmoduleStack.push(module);\n \t\tconfig.currentModule = module;\n \t\texecuteNow.call(module.testEnvironment, moduleFns);\n \t\tmoduleStack.pop();\n \t\tmodule = module.parentModule || currentModule;\n \t}\n\n \tconfig.currentModule = module;\n\n \tfunction setHookFromEnvironment(hooks, environment, name) {\n \t\tvar potentialHook = environment[name];\n \t\thooks[name] = typeof potentialHook === "function" ? [potentialHook] : [];\n \t\tdelete environment[name];\n \t}\n\n \tfunction setHookFunction(module, hookName) {\n \t\treturn function setHook(callback) {\n \t\t\tmodule.hooks[hookName].push(callback);\n \t\t};\n \t}\n }\n\n function module$1(name, options, executeNow) {\n \tif (focused && !isParentModuleInQueue()) {\n \t\treturn;\n \t}\n\n \tprocessModule(name, options, executeNow);\n }\n\n module$1.only = function () {\n \tif (!focused) {\n \t\tconfig.modules.length = 0;\n \t\tconfig.queue.length = 0;\n \t}\n\n \tprocessModule.apply(undefined, arguments);\n\n \tfocused = true;\n };\n\n module$1.skip = function (name, options, executeNow) {\n \tif (focused) {\n \t\treturn;\n \t}\n\n \tprocessModule(name, options, executeNow, { skip: true });\n };\n\n module$1.todo = function (name, options, executeNow) {\n \tif (focused) {\n \t\treturn;\n \t}\n\n \tprocessModule(name, options, executeNow, { todo: true });\n };\n\n var LISTENERS = Object.create(null);\n var SUPPORTED_EVENTS = ["runStart", "suiteStart", "testStart", "assertion", "testEnd", "suiteEnd", "runEnd"];\n\n /**\n * Emits an event with the specified data to all currently registered listeners.\n * Callbacks will fire in the order in which they are registered (FIFO). This\n * function is not exposed publicly; it is used by QUnit internals to emit\n * logging events.\n *\n * @private\n * @method emit\n * @param {String} eventName\n * @param {Object} data\n * @return {Void}\n */\n function emit(eventName, data) {\n \tif (objectType(eventName) !== "string") {\n \t\tthrow new TypeError("eventName must be a string when emitting an event");\n \t}\n\n \t// Clone the callbacks in case one of them registers a new callback\n \tvar originalCallbacks = LISTENERS[eventName];\n \tvar callbacks = originalCallbacks ? [].concat(toConsumableArray(originalCallbacks)) : [];\n\n \tfor (var i = 0; i < callbacks.length; i++) {\n \t\tcallbacks[i](data);\n \t}\n }\n\n /**\n * Registers a callback as a listener to the specified event.\n *\n * @public\n * @method on\n * @param {String} eventName\n * @param {Function} callback\n * @return {Void}\n */\n function on(eventName, callback) {\n \tif (objectType(eventName) !== "string") {\n \t\tthrow new TypeError("eventName must be a string when registering a listener");\n \t} else if (!inArray(eventName, SUPPORTED_EVENTS)) {\n \t\tvar events = SUPPORTED_EVENTS.join(", ");\n \t\tthrow new Error("\\"" + eventName + "\\" is not a valid event; must be one of: " + events + ".");\n \t} else if (objectType(callback) !== "function") {\n \t\tthrow new TypeError("callback must be a function when registering a listener");\n \t}\n\n \tif (!LISTENERS[eventName]) {\n \t\tLISTENERS[eventName] = [];\n \t}\n\n \t// Don\'t register the same callback more than once\n \tif (!inArray(callback, LISTENERS[eventName])) {\n \t\tLISTENERS[eventName].push(callback);\n \t}\n }\n\n function objectOrFunction(x) {\n var type = typeof x === \'undefined\' ? \'undefined\' : _typeof(x);\n return x !== null && (type === \'object\' || type === \'function\');\n }\n\n function isFunction(x) {\n return typeof x === \'function\';\n }\n\n\n\n var _isArray = void 0;\n if (Array.isArray) {\n _isArray = Array.isArray;\n } else {\n _isArray = function _isArray(x) {\n return Object.prototype.toString.call(x) === \'[object Array]\';\n };\n }\n\n var isArray = _isArray;\n\n var len = 0;\n var vertxNext = void 0;\n var customSchedulerFn = void 0;\n\n var asap = function asap(callback, arg) {\n queue[len] = callback;\n queue[len + 1] = arg;\n len += 2;\n if (len === 2) {\n // If len is 2, that means that we need to schedule an async flush.\n // If additional callbacks are queued before the queue is flushed, they\n // will be processed by this flush that we are scheduling.\n if (customSchedulerFn) {\n customSchedulerFn(flush);\n } else {\n scheduleFlush();\n }\n }\n };\n\n function setScheduler(scheduleFn) {\n customSchedulerFn = scheduleFn;\n }\n\n function setAsap(asapFn) {\n asap = asapFn;\n }\n\n var browserWindow = typeof window !== \'undefined\' ? window : undefined;\n var browserGlobal = browserWindow || {};\n var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;\n var isNode = typeof self === \'undefined\' && typeof process !== \'undefined\' && {}.toString.call(process) === \'[object process]\';\n\n // test for web worker but not in IE10\n var isWorker = typeof Uint8ClampedArray !== \'undefined\' && typeof importScripts !== \'undefined\' && typeof MessageChannel !== \'undefined\';\n\n // node\n function useNextTick() {\n // node version 0.10.x displays a deprecation warning when nextTick is used recursively\n // see https://github.com/cujojs/when/issues/410 for details\n return function () {\n return process.nextTick(flush);\n };\n }\n\n // vertx\n function useVertxTimer() {\n if (typeof vertxNext !== \'undefined\') {\n return function () {\n vertxNext(flush);\n };\n }\n\n return useSetTimeout();\n }\n\n function useMutationObserver() {\n var iterations = 0;\n var observer = new BrowserMutationObserver(flush);\n var node = document.createTextNode(\'\');\n observer.observe(node, { characterData: true });\n\n return function () {\n node.data = iterations = ++iterations % 2;\n };\n }\n\n // web worker\n function useMessageChannel() {\n var channel = new MessageChannel();\n channel.port1.onmessage = flush;\n return function () {\n return channel.port2.postMessage(0);\n };\n }\n\n function useSetTimeout() {\n // Store setTimeout reference so es6-promise will be unaffected by\n // other code modifying setTimeout (like sinon.useFakeTimers())\n var globalSetTimeout = setTimeout;\n return function () {\n return globalSetTimeout(flush, 1);\n };\n }\n\n var queue = new Array(1000);\n function flush() {\n for (var i = 0; i < len; i += 2) {\n var callback = queue[i];\n var arg = queue[i + 1];\n\n callback(arg);\n\n queue[i] = undefined;\n queue[i + 1] = undefined;\n }\n\n len = 0;\n }\n\n function attemptVertx() {\n try {\n var vertx = Function(\'return this\')().require(\'vertx\');\n vertxNext = vertx.runOnLoop || vertx.runOnContext;\n return useVertxTimer();\n } catch (e) {\n return useSetTimeout();\n }\n }\n\n var scheduleFlush = void 0;\n // Decide what async method to use to triggering processing of queued callbacks:\n if (isNode) {\n scheduleFlush = useNextTick();\n } else if (BrowserMutationObserver) {\n scheduleFlush = useMutationObserver();\n } else if (isWorker) {\n scheduleFlush = useMessageChannel();\n } else if (browserWindow === undefined && typeof require === \'function\') {\n scheduleFlush = attemptVertx();\n } else {\n scheduleFlush = useSetTimeout();\n }\n\n function then(onFulfillment, onRejection) {\n var parent = this;\n\n var child = new this.constructor(noop);\n\n if (child[PROMISE_ID] === undefined) {\n makePromise(child);\n }\n\n var _state = parent._state;\n\n\n if (_state) {\n var callback = arguments[_state - 1];\n asap(function () {\n return invokeCallback(_state, child, callback, parent._result);\n });\n } else {\n subscribe(parent, child, onFulfillment, onRejection);\n }\n\n return child;\n }\n\n /**\n `Promise.resolve` returns a promise that will become resolved with the\n passed `value`. It is shorthand for the following:\n\n ```javascript\n let promise = new Promise(function(resolve, reject){\n resolve(1);\n });\n\n promise.then(function(value){\n // value === 1\n });\n ```\n\n Instead of writing the above, your code now simply becomes the following:\n\n ```javascript\n let promise = Promise.resolve(1);\n\n promise.then(function(value){\n // value === 1\n });\n ```\n\n @method resolve\n @static\n @param {Any} value value that the returned promise will be resolved with\n Useful for tooling.\n @return {Promise} a promise that will become fulfilled with the given\n `value`\n */\n function resolve$1(object) {\n /*jshint validthis:true */\n var Constructor = this;\n\n if (object && (typeof object === \'undefined\' ? \'undefined\' : _typeof(object)) === \'object\' && object.constructor === Constructor) {\n return object;\n }\n\n var promise = new Constructor(noop);\n resolve(promise, object);\n return promise;\n }\n\n var PROMISE_ID = Math.random().toString(36).substring(2);\n\n function noop() {}\n\n var PENDING = void 0;\n var FULFILLED = 1;\n var REJECTED = 2;\n\n function selfFulfillment() {\n return new TypeError("You cannot resolve a promise with itself");\n }\n\n function cannotReturnOwn() {\n return new TypeError(\'A promises callback cannot return that same promise.\');\n }\n\n function tryThen(then$$1, value, fulfillmentHandler, rejectionHandler) {\n try {\n then$$1.call(value, fulfillmentHandler, rejectionHandler);\n } catch (e) {\n return e;\n }\n }\n\n function handleForeignThenable(promise, thenable, then$$1) {\n asap(function (promise) {\n var sealed = false;\n var error = tryThen(then$$1, thenable, function (value) {\n if (sealed) {\n return;\n }\n sealed = true;\n if (thenable !== value) {\n resolve(promise, value);\n } else {\n fulfill(promise, value);\n }\n }, function (reason) {\n if (sealed) {\n return;\n }\n sealed = true;\n\n reject(promise, reason);\n }, \'Settle: \' + (promise._label || \' unknown promise\'));\n\n if (!sealed && error) {\n sealed = true;\n reject(promise, error);\n }\n }, promise);\n }\n\n function handleOwnThenable(promise, thenable) {\n if (thenable._state === FULFILLED) {\n fulfill(promise, thenable._result);\n } else if (thenable._state === REJECTED) {\n reject(promise, thenable._result);\n } else {\n subscribe(thenable, undefined, function (value) {\n return resolve(promise, value);\n }, function (reason) {\n return reject(promise, reason);\n });\n }\n }\n\n function handleMaybeThenable(promise, maybeThenable, then$$1) {\n if (maybeThenable.constructor === promise.constructor && then$$1 === then && maybeThenable.constructor.resolve === resolve$1) {\n handleOwnThenable(promise, maybeThenable);\n } else {\n if (then$$1 === undefined) {\n fulfill(promise, maybeThenable);\n } else if (isFunction(then$$1)) {\n handleForeignThenable(promise, maybeThenable, then$$1);\n } else {\n fulfill(promise, maybeThenable);\n }\n }\n }\n\n function resolve(promise, value) {\n if (promise === value) {\n reject(promise, selfFulfillment());\n } else if (objectOrFunction(value)) {\n var then$$1 = void 0;\n try {\n then$$1 = value.then;\n } catch (error) {\n reject(promise, error);\n return;\n }\n handleMaybeThenable(promise, value, then$$1);\n } else {\n fulfill(promise, value);\n }\n }\n\n function publishRejection(promise) {\n if (promise._onerror) {\n promise._onerror(promise._result);\n }\n\n publish(promise);\n }\n\n function fulfill(promise, value) {\n if (promise._state !== PENDING) {\n return;\n }\n\n promise._result = value;\n promise._state = FULFILLED;\n\n if (promise._subscribers.length !== 0) {\n asap(publish, promise);\n }\n }\n\n function reject(promise, reason) {\n if (promise._state !== PENDING) {\n return;\n }\n promise._state = REJECTED;\n promise._result = reason;\n\n asap(publishRejection, promise);\n }\n\n function subscribe(parent, child, onFulfillment, onRejection) {\n var _subscribers = parent._subscribers;\n var length = _subscribers.length;\n\n\n parent._onerror = null;\n\n _subscribers[length] = child;\n _subscribers[length + FULFILLED] = onFulfillment;\n _subscribers[length + REJECTED] = onRejection;\n\n if (length === 0 && parent._state) {\n asap(publish, parent);\n }\n }\n\n function publish(promise) {\n var subscribers = promise._subscribers;\n var settled = promise._state;\n\n if (subscribers.length === 0) {\n return;\n }\n\n var child = void 0,\n callback = void 0,\n detail = promise._result;\n\n for (var i = 0; i < subscribers.length; i += 3) {\n child = subscribers[i];\n callback = subscribers[i + settled];\n\n if (child) {\n invokeCallback(settled, child, callback, detail);\n } else {\n callback(detail);\n }\n }\n\n promise._subscribers.length = 0;\n }\n\n function invokeCallback(settled, promise, callback, detail) {\n var hasCallback = isFunction(callback),\n value = void 0,\n error = void 0,\n succeeded = true;\n\n if (hasCallback) {\n try {\n value = callback(detail);\n } catch (e) {\n succeeded = false;\n error = e;\n }\n\n if (promise === value) {\n reject(promise, cannotReturnOwn());\n return;\n }\n } else {\n value = detail;\n }\n\n if (promise._state !== PENDING) {\n // noop\n } else if (hasCallback && succeeded) {\n resolve(promise, value);\n } else if (succeeded === false) {\n reject(promise, error);\n } else if (settled === FULFILLED) {\n fulfill(promise, value);\n } else if (settled === REJECTED) {\n reject(promise, value);\n }\n }\n\n function initializePromise(promise, resolver) {\n try {\n resolver(function resolvePromise(value) {\n resolve(promise, value);\n }, function rejectPromise(reason) {\n reject(promise, reason);\n });\n } catch (e) {\n reject(promise, e);\n }\n }\n\n var id = 0;\n function nextId() {\n return id++;\n }\n\n function makePromise(promise) {\n promise[PROMISE_ID] = id++;\n promise._state = undefined;\n promise._result = undefined;\n promise._subscribers = [];\n }\n\n function validationError() {\n return new Error(\'Array Methods must be provided an Array\');\n }\n\n var Enumerator = function () {\n function Enumerator(Constructor, input) {\n classCallCheck(this, Enumerator);\n\n this._instanceConstructor = Constructor;\n this.promise = new Constructor(noop);\n\n if (!this.promise[PROMISE_ID]) {\n makePromise(this.promise);\n }\n\n if (isArray(input)) {\n this.length = input.length;\n this._remaining = input.length;\n\n this._result = new Array(this.length);\n\n if (this.length === 0) {\n fulfill(this.promise, this._result);\n } else {\n this.length = this.length || 0;\n this._enumerate(input);\n if (this._remaining === 0) {\n fulfill(this.promise, this._result);\n }\n }\n } else {\n reject(this.promise, validationError());\n }\n }\n\n createClass(Enumerator, [{\n key: \'_enumerate\',\n value: function _enumerate(input) {\n for (var i = 0; this._state === PENDING && i < input.length; i++) {\n this._eachEntry(input[i], i);\n }\n }\n }, {\n key: \'_eachEntry\',\n value: function _eachEntry(entry, i) {\n var c = this._instanceConstructor;\n var resolve$$1 = c.resolve;\n\n\n if (resolve$$1 === resolve$1) {\n var _then = void 0;\n var error = void 0;\n var didError = false;\n try {\n _then = entry.then;\n } catch (e) {\n didError = true;\n error = e;\n }\n\n if (_then === then && entry._state !== PENDING) {\n this._settledAt(entry._state, i, entry._result);\n } else if (typeof _then !== \'function\') {\n this._remaining--;\n this._result[i] = entry;\n } else if (c === Promise$2) {\n var promise = new c(noop);\n if (didError) {\n reject(promise, error);\n } else {\n handleMaybeThenable(promise, entry, _then);\n }\n this._willSettleAt(promise, i);\n } else {\n this._willSettleAt(new c(function (resolve$$1) {\n return resolve$$1(entry);\n }), i);\n }\n } else {\n this._willSettleAt(resolve$$1(entry), i);\n }\n }\n }, {\n key: \'_settledAt\',\n value: function _settledAt(state, i, value) {\n var promise = this.promise;\n\n\n if (promise._state === PENDING) {\n this._remaining--;\n\n if (state === REJECTED) {\n reject(promise, value);\n } else {\n this._result[i] = value;\n }\n }\n\n if (this._remaining === 0) {\n fulfill(promise, this._result);\n }\n }\n }, {\n key: \'_willSettleAt\',\n value: function _willSettleAt(promise, i) {\n var enumerator = this;\n\n subscribe(promise, undefined, function (value) {\n return enumerator._settledAt(FULFILLED, i, value);\n }, function (reason) {\n return enumerator._settledAt(REJECTED, i, reason);\n });\n }\n }]);\n return Enumerator;\n }();\n\n /**\n `Promise.all` accepts an array of promises, and returns a new promise which\n is fulfilled with an array of fulfillment values for the passed promises, or\n rejected with the reason of the first passed promise to be rejected. It casts all\n elements of the passed iterable to promises as it runs this algorithm.\n\n Example:\n\n ```javascript\n let promise1 = resolve(1);\n let promise2 = resolve(2);\n let promise3 = resolve(3);\n let promises = [ promise1, promise2, promise3 ];\n\n Promise.all(promises).then(function(array){\n // The array here would be [ 1, 2, 3 ];\n });\n ```\n\n If any of the `promises` given to `all` are rejected, the first promise\n that is rejected will be given as an argument to the returned promises\'s\n rejection handler. For example:\n\n Example:\n\n ```javascript\n let promise1 = resolve(1);\n let promise2 = reject(new Error("2"));\n let promise3 = reject(new Error("3"));\n let promises = [ promise1, promise2, promise3 ];\n\n Promise.all(promises).then(function(array){\n // Code here never runs because there are rejected promises!\n }, function(error) {\n // error.message === "2"\n });\n ```\n\n @method all\n @static\n @param {Array} entries array of promises\n @param {String} label optional string for labeling the promise.\n Useful for tooling.\n @return {Promise} promise that is fulfilled when all `promises` have been\n fulfilled, or rejected if any of them become rejected.\n @static\n */\n function all(entries) {\n return new Enumerator(this, entries).promise;\n }\n\n /**\n `Promise.race` returns a new promise which is settled in the same way as the\n first passed promise to settle.\n\n Example:\n\n ```javascript\n let promise1 = new Promise(function(resolve, reject){\n setTimeout(function(){\n resolve(\'promise 1\');\n }, 200);\n });\n\n let promise2 = new Promise(function(resolve, reject){\n setTimeout(function(){\n resolve(\'promise 2\');\n }, 100);\n });\n\n Promise.race([promise1, promise2]).then(function(result){\n // result === \'promise 2\' because it was resolved before promise1\n // was resolved.\n });\n ```\n\n `Promise.race` is deterministic in that only the state of the first\n settled promise matters. For example, even if other promises given to the\n `promises` array argument are resolved, but the first settled promise has\n become rejected before the other promises became fulfilled, the returned\n promise will become rejected:\n\n ```javascript\n let promise1 = new Promise(function(resolve, reject){\n setTimeout(function(){\n resolve(\'promise 1\');\n }, 200);\n });\n\n let promise2 = new Promise(function(resolve, reject){\n setTimeout(function(){\n reject(new Error(\'promise 2\'));\n }, 100);\n });\n\n Promise.race([promise1, promise2]).then(function(result){\n // Code here never runs\n }, function(reason){\n // reason.message === \'promise 2\' because promise 2 became rejected before\n // promise 1 became fulfilled\n });\n ```\n\n An example real-world use case is implementing timeouts:\n\n ```javascript\n Promise.race([ajax(\'foo.json\'), timeout(5000)])\n ```\n\n @method race\n @static\n @param {Array} promises array of promises to observe\n Useful for tooling.\n @return {Promise} a promise which settles in the same way as the first passed\n promise to settle.\n */\n function race(entries) {\n /*jshint validthis:true */\n var Constructor = this;\n\n if (!isArray(entries)) {\n return new Constructor(function (_, reject) {\n return reject(new TypeError(\'You must pass an array to race.\'));\n });\n } else {\n return new Constructor(function (resolve, reject) {\n var length = entries.length;\n for (var i = 0; i < length; i++) {\n Constructor.resolve(entries[i]).then(resolve, reject);\n }\n });\n }\n }\n\n /**\n `Promise.reject` returns a promise rejected with the passed `reason`.\n It is shorthand for the following:\n\n ```javascript\n let promise = new Promise(function(resolve, reject){\n reject(new Error(\'WHOOPS\'));\n });\n\n promise.then(function(value){\n // Code here doesn\'t run because the promise is rejected!\n }, function(reason){\n // reason.message === \'WHOOPS\'\n });\n ```\n\n Instead of writing the above, your code now simply becomes the following:\n\n ```javascript\n let promise = Promise.reject(new Error(\'WHOOPS\'));\n\n promise.then(function(value){\n // Code here doesn\'t run because the promise is rejected!\n }, function(reason){\n // reason.message === \'WHOOPS\'\n });\n ```\n\n @method reject\n @static\n @param {Any} reason value that the returned promise will be rejected with.\n Useful for tooling.\n @return {Promise} a promise rejected with the given `reason`.\n */\n function reject$1(reason) {\n /*jshint validthis:true */\n var Constructor = this;\n var promise = new Constructor(noop);\n reject(promise, reason);\n return promise;\n }\n\n function needsResolver() {\n throw new TypeError(\'You must pass a resolver function as the first argument to the promise constructor\');\n }\n\n function needsNew() {\n throw new TypeError("Failed to construct \'Promise\': Please use the \'new\' operator, this object constructor cannot be called as a function.");\n }\n\n /**\n Promise objects represent the eventual result of an asynchronous operation. The\n primary way of interacting with a promise is through its `then` method, which\n registers callbacks to receive either a promise\'s eventual value or the reason\n why the promise cannot be fulfilled.\n\n Terminology\n -----------\n\n - `promise` is an object or function with a `then` method whose behavior conforms to this specification.\n - `thenable` is an object or function that defines a `then` method.\n - `value` is any legal JavaScript value (including undefined, a thenable, or a promise).\n - `exception` is a value that is thrown using the throw statement.\n - `reason` is a value that indicates why a promise was rejected.\n - `settled` the final resting state of a promise, fulfilled or rejected.\n\n A promise can be in one of three states: pending, fulfilled, or rejected.\n\n Promises that are fulfilled have a fulfillment value and are in the fulfilled\n state. Promises that are rejected have a rejection reason and are in the\n rejected state. A fulfillment value is never a thenable.\n\n Promises can also be said to *resolve* a value. If this value is also a\n promise, then the original promise\'s settled state will match the value\'s\n settled state. So a promise that *resolves* a promise that rejects will\n itself reject, and a promise that *resolves* a promise that fulfills will\n itself fulfill.\n\n\n Basic Usage:\n ------------\n\n ```js\n let promise = new Promise(function(resolve, reject) {\n // on success\n resolve(value);\n\n // on failure\n reject(reason);\n });\n\n promise.then(function(value) {\n // on fulfillment\n }, function(reason) {\n // on rejection\n });\n ```\n\n Advanced Usage:\n ---------------\n\n Promises shine when abstracting away asynchronous interactions such as\n `XMLHttpRequest`s.\n\n ```js\n function getJSON(url) {\n return new Promise(function(resolve, reject){\n let xhr = new XMLHttpRequest();\n\n xhr.open(\'GET\', url);\n xhr.onreadystatechange = handler;\n xhr.responseType = \'json\';\n xhr.setRequestHeader(\'Accept\', \'application/json\');\n xhr.send();\n\n function handler() {\n if (this.readyState === this.DONE) {\n if (this.status === 200) {\n resolve(this.response);\n } else {\n reject(new Error(\'getJSON: `\' + url + \'` failed with status: [\' + this.status + \']\'));\n }\n }\n };\n });\n }\n\n getJSON(\'/posts.json\').then(function(json) {\n // on fulfillment\n }, function(reason) {\n // on rejection\n });\n ```\n\n Unlike callbacks, promises are great composable primitives.\n\n ```js\n Promise.all([\n getJSON(\'/posts\'),\n getJSON(\'/comments\')\n ]).then(function(values){\n values[0] // => postsJSON\n values[1] // => commentsJSON\n\n return values;\n });\n ```\n\n @class Promise\n @param {Function} resolver\n Useful for tooling.\n @constructor\n */\n\n var Promise$2 = function () {\n function Promise(resolver) {\n classCallCheck(this, Promise);\n\n this[PROMISE_ID] = nextId();\n this._result = this._state = undefined;\n this._subscribers = [];\n\n if (noop !== resolver) {\n typeof resolver !== \'function\' && needsResolver();\n this instanceof Promise ? initializePromise(this, resolver) : needsNew();\n }\n }\n\n /**\n The primary way of interacting with a promise is through its `then` method,\n which registers callbacks to receive either a promise\'s eventual value or the\n reason why the promise cannot be fulfilled.\n ```js\n findUser().then(function(user){\n // user is available\n }, function(reason){\n // user is unavailable, and you are given the reason why\n });\n ```\n Chaining\n --------\n The return value of `then` is itself a promise. This second, \'downstream\'\n promise is resolved with the return value of the first promise\'s fulfillment\n or rejection handler, or rejected if the handler throws an exception.\n ```js\n findUser().then(function (user) {\n return user.name;\n }, function (reason) {\n return \'default name\';\n }).then(function (userName) {\n // If `findUser` fulfilled, `userName` will be the user\'s name, otherwise it\n // will be `\'default name\'`\n });\n findUser().then(function (user) {\n throw new Error(\'Found user, but still unhappy\');\n }, function (reason) {\n throw new Error(\'`findUser` rejected and we\'re unhappy\');\n }).then(function (value) {\n // never reached\n }, function (reason) {\n // if `findUser` fulfilled, `reason` will be \'Found user, but still unhappy\'.\n // If `findUser` rejected, `reason` will be \'`findUser` rejected and we\'re unhappy\'.\n });\n ```\n If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.\n ```js\n findUser().then(function (user) {\n throw new PedagogicalException(\'Upstream error\');\n }).then(function (value) {\n // never reached\n }).then(function (value) {\n // never reached\n }, function (reason) {\n // The `PedgagocialException` is propagated all the way down to here\n });\n ```\n Assimilation\n ------------\n Sometimes the value you want to propagate to a downstream promise can only be\n retrieved asynchronously. This can be achieved by returning a promise in the\n fulfillment or rejection handler. The downstream promise will then be pending\n until the returned promise is settled. This is called *assimilation*.\n ```js\n findUser().then(function (user) {\n return findCommentsByAuthor(user);\n }).then(function (comments) {\n // The user\'s comments are now available\n });\n ```\n If the assimliated promise rejects, then the downstream promise will also reject.\n ```js\n findUser().then(function (user) {\n return findCommentsByAuthor(user);\n }).then(function (comments) {\n // If `findCommentsByAuthor` fulfills, we\'ll have the value here\n }, function (reason) {\n // If `findCommentsByAuthor` rejects, we\'ll have the reason here\n });\n ```\n Simple Example\n --------------\n Synchronous Example\n ```javascript\n let result;\n try {\n result = findResult();\n // success\n } catch(reason) {\n // failure\n }\n ```\n Errback Example\n ```js\n findResult(function(result, err){\n if (err) {\n // failure\n } else {\n // success\n }\n });\n ```\n Promise Example;\n ```javascript\n findResult().then(function(result){\n // success\n }, function(reason){\n // failure\n });\n ```\n Advanced Example\n --------------\n Synchronous Example\n ```javascript\n let author, books;\n try {\n author = findAuthor();\n books = findBooksByAuthor(author);\n // success\n } catch(reason) {\n // failure\n }\n ```\n Errback Example\n ```js\n function foundBooks(books) {\n }\n function failure(reason) {\n }\n findAuthor(function(author, err){\n if (err) {\n failure(err);\n // failure\n } else {\n try {\n findBoooksByAuthor(author, function(books, err) {\n if (err) {\n failure(err);\n } else {\n try {\n foundBooks(books);\n } catch(reason) {\n failure(reason);\n }\n }\n });\n } catch(error) {\n failure(err);\n }\n // success\n }\n });\n ```\n Promise Example;\n ```javascript\n findAuthor().\n then(findBooksByAuthor).\n then(function(books){\n // found books\n }).catch(function(reason){\n // something went wrong\n });\n ```\n @method then\n @param {Function} onFulfilled\n @param {Function} onRejected\n Useful for tooling.\n @return {Promise}\n */\n\n /**\n `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same\n as the catch block of a try/catch statement.\n ```js\n function findAuthor(){\n throw new Error(\'couldn\'t find that author\');\n }\n // synchronous\n try {\n findAuthor();\n } catch(reason) {\n // something went wrong\n }\n // async with promises\n findAuthor().catch(function(reason){\n // something went wrong\n });\n ```\n @method catch\n @param {Function} onRejection\n Useful for tooling.\n @return {Promise}\n */\n\n\n createClass(Promise, [{\n key: \'catch\',\n value: function _catch(onRejection) {\n return this.then(null, onRejection);\n }\n\n /**\n `finally` will be invoked regardless of the promise\'s fate just as native\n try/catch/finally behaves\n \n Synchronous example:\n \n ```js\n findAuthor() {\n if (Math.random() > 0.5) {\n throw new Error();\n }\n return new Author();\n }\n \n try {\n return findAuthor(); // succeed or fail\n } catch(error) {\n return findOtherAuther();\n } finally {\n // always runs\n // doesn\'t affect the return value\n }\n ```\n \n Asynchronous example:\n \n ```js\n findAuthor().catch(function(reason){\n return findOtherAuther();\n }).finally(function(){\n // author was either found, or not\n });\n ```\n \n @method finally\n @param {Function} callback\n @return {Promise}\n */\n\n }, {\n key: \'finally\',\n value: function _finally(callback) {\n var promise = this;\n var constructor = promise.constructor;\n\n if (isFunction(callback)) {\n return promise.then(function (value) {\n return constructor.resolve(callback()).then(function () {\n return value;\n });\n }, function (reason) {\n return constructor.resolve(callback()).then(function () {\n throw reason;\n });\n });\n }\n\n return promise.then(callback, callback);\n }\n }]);\n return Promise;\n }();\n\n Promise$2.prototype.then = then;\n Promise$2.all = all;\n Promise$2.race = race;\n Promise$2.resolve = resolve$1;\n Promise$2.reject = reject$1;\n Promise$2._setScheduler = setScheduler;\n Promise$2._setAsap = setAsap;\n Promise$2._asap = asap;\n\n /*global self*/\n function polyfill() {\n var local = void 0;\n\n if (typeof global !== \'undefined\') {\n local = global;\n } else if (typeof self !== \'undefined\') {\n local = self;\n } else {\n try {\n local = Function(\'return this\')();\n } catch (e) {\n throw new Error(\'polyfill failed because global object is unavailable in this environment\');\n }\n }\n\n var P = local.Promise;\n\n if (P) {\n var promiseToString = null;\n try {\n promiseToString = Object.prototype.toString.call(P.resolve());\n } catch (e) {\n // silently ignored\n }\n\n if (promiseToString === \'[object Promise]\' && !P.cast) {\n return;\n }\n }\n\n local.Promise = Promise$2;\n }\n\n // Strange compat..\n Promise$2.polyfill = polyfill;\n Promise$2.Promise = Promise$2;\n\n var Promise$1 = typeof Promise !== "undefined" ? Promise : Promise$2;\n\n // Register logging callbacks\n function registerLoggingCallbacks(obj) {\n \tvar i,\n \t l,\n \t key,\n \t callbackNames = ["begin", "done", "log", "testStart", "testDone", "moduleStart", "moduleDone"];\n\n \tfunction registerLoggingCallback(key) {\n \t\tvar loggingCallback = function loggingCallback(callback) {\n \t\t\tif (objectType(callback) !== "function") {\n \t\t\t\tthrow new Error("QUnit logging methods require a callback function as their first parameters.");\n \t\t\t}\n\n \t\t\tconfig.callbacks[key].push(callback);\n \t\t};\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\n function runLoggingCallbacks(key, args) {\n \tvar callbacks = config.callbacks[key];\n\n \t// Handling \'log\' callbacks separately. Unlike the other callbacks,\n \t// the log callback is not controlled by the processing queue,\n \t// but rather used by asserts. Hence to promisfy the \'log\' callback\n \t// would mean promisfying each step of a test\n \tif (key === "log") {\n \t\tcallbacks.map(function (callback) {\n \t\t\treturn callback(args);\n \t\t});\n \t\treturn;\n \t}\n\n \t// ensure that each callback is executed serially\n \treturn callbacks.reduce(function (promiseChain, callback) {\n \t\treturn promiseChain.then(function () {\n \t\t\treturn Promise$1.resolve(callback(args));\n \t\t});\n \t}, Promise$1.resolve([]));\n }\n\n // Doesn\'t support IE9, it will return undefined on these browsers\n // See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack\n var fileName = (sourceFromStacktrace(0) || "").replace(/(:\\d+)+\\)?/, "").replace(/.+\\//, "");\n\n function extractStacktrace(e, offset) {\n \toffset = offset === undefined ? 4 : offset;\n\n \tvar stack, include, i;\n\n \tif (e && 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 \t}\n }\n\n function 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 var priorityCount = 0;\n var unitSampler = void 0;\n\n // This is a queue of functions that are tasks within a single test.\n // After tests are dequeued from config.queue they are expanded into\n // a set of tasks in this queue.\n var taskQueue = [];\n\n /**\n * Advances the taskQueue to the next task. If the taskQueue is empty,\n * process the testQueue\n */\n function advance() {\n \tadvanceTaskQueue();\n\n \tif (!taskQueue.length && !config.blocking && !config.current) {\n \t\tadvanceTestQueue();\n \t}\n }\n\n /**\n * Advances the taskQueue with an increased depth\n */\n function advanceTaskQueue() {\n \tvar start = now();\n \tconfig.depth = (config.depth || 0) + 1;\n\n \tprocessTaskQueue(start);\n\n \tconfig.depth--;\n }\n\n /**\n * Process the first task on the taskQueue as a promise.\n * Each task is a function returned by https://github.com/qunitjs/qunit/blob/master/src/test.js#L381\n */\n function processTaskQueue(start) {\n \tif (taskQueue.length && !config.blocking) {\n \t\tvar elapsedTime = now() - start;\n\n \t\tif (!defined.setTimeout || config.updateRate <= 0 || elapsedTime < config.updateRate) {\n \t\t\tvar task = taskQueue.shift();\n \t\t\tPromise$1.resolve(task()).then(function () {\n \t\t\t\tif (!taskQueue.length) {\n \t\t\t\t\tadvance();\n \t\t\t\t} else {\n \t\t\t\t\tprocessTaskQueue(start);\n \t\t\t\t}\n \t\t\t});\n \t\t} else {\n \t\t\tsetTimeout$1(advance);\n \t\t}\n \t}\n }\n\n /**\n * Advance the testQueue to the next test to process. Call done() if testQueue completes.\n */\n function advanceTestQueue() {\n \tif (!config.blocking && !config.queue.length && config.depth === 0) {\n \t\tdone();\n \t\treturn;\n \t}\n\n \tvar testTasks = config.queue.shift();\n \taddToTaskQueue(testTasks());\n\n \tif (priorityCount > 0) {\n \t\tpriorityCount--;\n \t}\n\n \tadvance();\n }\n\n /**\n * Enqueue the tasks for a test into the task queue.\n * @param {Array} tasksArray\n */\n function addToTaskQueue(tasksArray) {\n \ttaskQueue.push.apply(taskQueue, toConsumableArray(tasksArray));\n }\n\n /**\n * Return the number of tasks remaining in the task queue to be processed.\n * @return {Number}\n */\n function taskQueueLength() {\n \treturn taskQueue.length;\n }\n\n /**\n * Adds a test to the TestQueue for execution.\n * @param {Function} testTasksFunc\n * @param {Boolean} prioritize\n * @param {String} seed\n */\n function addToTestQueue(testTasksFunc, prioritize, seed) {\n \tif (prioritize) {\n \t\tconfig.queue.splice(priorityCount++, 0, testTasksFunc);\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 prioritized items\n \t\tvar index = Math.floor(unitSampler() * (config.queue.length - priorityCount + 1));\n \t\tconfig.queue.splice(priorityCount + index, 0, testTasksFunc);\n \t} else {\n \t\tconfig.queue.push(testTasksFunc);\n \t}\n }\n\n /**\n * Creates a seeded "sample" generator which is used for randomizing tests.\n */\n function 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\n /**\n * This function is called when the ProcessingQueue is done processing all\n * items. It handles emitting the final run events.\n */\n function done() {\n \tvar storage = config.storage;\n\n \tProcessingQueue.finished = true;\n\n \tvar runtime = now() - config.started;\n \tvar passed = config.stats.all - config.stats.bad;\n\n \tif (config.stats.all === 0) {\n\n \t\tif (config.filter && config.filter.length) {\n \t\t\tthrow new Error("No tests matched the filter \\"" + config.filter + "\\".");\n \t\t}\n\n \t\tif (config.module && config.module.length) {\n \t\t\tthrow new Error("No tests matched the module \\"" + config.module + "\\".");\n \t\t}\n\n \t\tif (config.moduleId && config.moduleId.length) {\n \t\t\tthrow new Error("No tests matched the moduleId \\"" + config.moduleId + "\\".");\n \t\t}\n\n \t\tif (config.testId && config.testId.length) {\n \t\t\tthrow new Error("No tests matched the testId \\"" + config.testId + "\\".");\n \t\t}\n\n \t\tthrow new Error("No tests were run.");\n \t}\n\n \temit("runEnd", globalSuite.end(true));\n \trunLoggingCallbacks("done", {\n \t\tpassed: passed,\n \t\tfailed: config.stats.bad,\n \t\ttotal: config.stats.all,\n \t\truntime: runtime\n \t}).then(function () {\n\n \t\t// Clear own storage items if all tests passed\n \t\tif (storage && config.stats.bad === 0) {\n \t\t\tfor (var i = storage.length - 1; i >= 0; i--) {\n \t\t\t\tvar key = storage.key(i);\n\n \t\t\t\tif (key.indexOf("qunit-test-") === 0) {\n \t\t\t\t\tstorage.removeItem(key);\n \t\t\t\t}\n \t\t\t}\n \t\t}\n \t});\n }\n\n var ProcessingQueue = {\n \tfinished: false,\n \tadd: addToTestQueue,\n \tadvance: advance,\n \ttaskCount: taskQueueLength\n };\n\n var TestReport = function () {\n \tfunction TestReport(name, suite, options) {\n \t\tclassCallCheck(this, TestReport);\n\n \t\tthis.name = name;\n \t\tthis.suiteName = suite.name;\n \t\tthis.fullName = suite.fullName.concat(name);\n \t\tthis.runtime = 0;\n \t\tthis.assertions = [];\n\n \t\tthis.skipped = !!options.skip;\n \t\tthis.todo = !!options.todo;\n\n \t\tthis.valid = options.valid;\n\n \t\tthis._startTime = 0;\n \t\tthis._endTime = 0;\n\n \t\tsuite.pushTest(this);\n \t}\n\n \tcreateClass(TestReport, [{\n \t\tkey: "start",\n \t\tvalue: function start(recordTime) {\n \t\t\tif (recordTime) {\n \t\t\t\tthis._startTime = performanceNow();\n \t\t\t\tif (performance) {\n \t\t\t\t\tperformance.mark("qunit_test_start");\n \t\t\t\t}\n \t\t\t}\n\n \t\t\treturn {\n \t\t\t\tname: this.name,\n \t\t\t\tsuiteName: this.suiteName,\n \t\t\t\tfullName: this.fullName.slice()\n \t\t\t};\n \t\t}\n \t}, {\n \t\tkey: "end",\n \t\tvalue: function end(recordTime) {\n \t\t\tif (recordTime) {\n \t\t\t\tthis._endTime = performanceNow();\n \t\t\t\tif (performance) {\n \t\t\t\t\tperformance.mark("qunit_test_end");\n\n \t\t\t\t\tvar testName = this.fullName.join(" \u2013 ");\n\n \t\t\t\t\tmeasure("QUnit Test: " + testName, "qunit_test_start", "qunit_test_end");\n \t\t\t\t}\n \t\t\t}\n\n \t\t\treturn extend(this.start(), {\n \t\t\t\truntime: this.getRuntime(),\n \t\t\t\tstatus: this.getStatus(),\n \t\t\t\terrors: this.getFailedAssertions(),\n \t\t\t\tassertions: this.getAssertions()\n \t\t\t});\n \t\t}\n \t}, {\n \t\tkey: "pushAssertion",\n \t\tvalue: function pushAssertion(assertion) {\n \t\t\tthis.assertions.push(assertion);\n \t\t}\n \t}, {\n \t\tkey: "getRuntime",\n \t\tvalue: function getRuntime() {\n \t\t\treturn this._endTime - this._startTime;\n \t\t}\n \t}, {\n \t\tkey: "getStatus",\n \t\tvalue: function getStatus() {\n \t\t\tif (this.skipped) {\n \t\t\t\treturn "skipped";\n \t\t\t}\n\n \t\t\tvar testPassed = this.getFailedAssertions().length > 0 ? this.todo : !this.todo;\n\n \t\t\tif (!testPassed) {\n \t\t\t\treturn "failed";\n \t\t\t} else if (this.todo) {\n \t\t\t\treturn "todo";\n \t\t\t} else {\n \t\t\t\treturn "passed";\n \t\t\t}\n \t\t}\n \t}, {\n \t\tkey: "getFailedAssertions",\n \t\tvalue: function getFailedAssertions() {\n \t\t\treturn this.assertions.filter(function (assertion) {\n \t\t\t\treturn !assertion.passed;\n \t\t\t});\n \t\t}\n \t}, {\n \t\tkey: "getAssertions",\n \t\tvalue: function getAssertions() {\n \t\t\treturn this.assertions.slice();\n \t\t}\n\n \t\t// Remove actual and expected values from assertions. This is to prevent\n \t\t// leaking memory throughout a test suite.\n\n \t}, {\n \t\tkey: "slimAssertions",\n \t\tvalue: function slimAssertions() {\n \t\t\tthis.assertions = this.assertions.map(function (assertion) {\n \t\t\t\tdelete assertion.actual;\n \t\t\t\tdelete assertion.expected;\n \t\t\t\treturn assertion;\n \t\t\t});\n \t\t}\n \t}]);\n \treturn TestReport;\n }();\n\n var focused$1 = false;\n\n function Test(settings) {\n \tvar i, l;\n\n \t++Test.count;\n\n \tthis.expected = null;\n \tthis.assertions = [];\n \tthis.semaphore = 0;\n \tthis.module = config.currentModule;\n \tthis.steps = [];\n \tthis.timeout = undefined;\n \tthis.errorForStack = new Error();\n\n \t// If a module is skipped, all its tests and the tests of the child suites\n \t// should be treated as skipped even if they are defined as `only` or `todo`.\n \t// As for `todo` module, all its tests will be treated as `todo` except for\n \t// tests defined as `skip` which will be left intact.\n \t//\n \t// So, if a test is defined as `todo` and is inside a skipped module, we should\n \t// then treat that test as if was defined as `skip`.\n \tif (this.module.skip) {\n \t\tsettings.skip = true;\n \t\tsettings.todo = false;\n\n \t\t// Skipped tests should be left intact\n \t} else if (this.module.todo && !settings.skip) {\n \t\tsettings.todo = true;\n \t}\n\n \textend(this, settings);\n\n \tthis.testReport = new TestReport(settings.testName, this.module.suiteReport, {\n \t\ttodo: settings.todo,\n \t\tskip: settings.skip,\n \t\tvalid: this.valid()\n \t});\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\tskip: !!settings.skip\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\tif (typeof this.callback !== "function") {\n \t\t\tvar method = this.todo ? "todo" : "test";\n\n \t\t\t// eslint-disable-next-line max-len\n \t\t\tthrow new TypeError("You must provide a function as a test callback to QUnit." + method + "(\\"" + settings.testName + "\\")");\n \t\t}\n\n \t\tthis.assert = new Assert(this);\n \t}\n }\n\n Test.count = 0;\n\n function getNotStartedModules(startModule) {\n \tvar module = startModule,\n \t modules = [];\n\n \twhile (module && module.testsRun === 0) {\n \t\tmodules.push(module);\n \t\tmodule = module.parentModule;\n \t}\n\n \t// The above push modules from the child to the parent\n \t// return a reversed order with the top being the top most parent module\n \treturn modules.reverse();\n }\n\n Test.prototype = {\n\n \t// generating a stack trace can be expensive, so using a getter defers this until we need it\n \tget stack() {\n \t\treturn extractStacktrace(this.errorForStack, 2);\n \t},\n\n \tbefore: function before() {\n \t\tvar _this = this;\n\n \t\tvar module = this.module,\n \t\t notStartedModules = getNotStartedModules(module);\n\n \t\t// ensure the callbacks are executed serially for each module\n \t\tvar callbackPromises = notStartedModules.reduce(function (promiseChain, startModule) {\n \t\t\treturn promiseChain.then(function () {\n \t\t\t\tstartModule.stats = { all: 0, bad: 0, started: now() };\n \t\t\t\temit("suiteStart", startModule.suiteReport.start(true));\n \t\t\t\treturn runLoggingCallbacks("moduleStart", {\n \t\t\t\t\tname: startModule.name,\n \t\t\t\t\ttests: startModule.tests\n \t\t\t\t});\n \t\t\t});\n \t\t}, Promise$1.resolve([]));\n\n \t\treturn callbackPromises.then(function () {\n \t\t\tconfig.current = _this;\n\n \t\t\t_this.testEnvironment = extend({}, module.testEnvironment);\n\n \t\t\t_this.started = now();\n \t\t\temit("testStart", _this.testReport.start(true));\n \t\t\treturn runLoggingCallbacks("testStart", {\n \t\t\t\tname: _this.testName,\n \t\t\t\tmodule: module.name,\n \t\t\t\ttestId: _this.testId,\n \t\t\t\tpreviousFailure: _this.previousFailure\n \t\t\t}).then(function () {\n \t\t\t\tif (!config.pollution) {\n \t\t\t\t\tsaveGlobal();\n \t\t\t\t}\n \t\t\t});\n \t\t});\n \t},\n\n \trun: function run() {\n \t\tvar promise;\n\n \t\tconfig.current = this;\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) + " " + this.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\tinternalRecover(this);\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\n \t\t\t// If the test has a "lock" on it, but the timeout is 0, then we push a\n \t\t\t// failure as the test should be synchronous.\n \t\t\tif (test.timeout === 0 && test.semaphore !== 0) {\n \t\t\t\tpushFailure("Test did not finish synchronously even though assert.timeout( 0 ) was used.", sourceFromStacktrace(2));\n \t\t\t}\n \t\t}\n \t},\n\n \tafter: function after() {\n \t\tcheckPollution();\n \t},\n\n \tqueueHook: function queueHook(hook, hookName, hookOwner) {\n \t\tvar _this2 = this;\n\n \t\tvar callHook = function callHook() {\n \t\t\tvar promise = hook.call(_this2.testEnvironment, _this2.assert);\n \t\t\t_this2.resolvePromise(promise, hookName);\n \t\t};\n\n \t\tvar runHook = function runHook() {\n \t\t\tif (hookName === "before") {\n \t\t\t\tif (hookOwner.unskippedTestsRun !== 0) {\n \t\t\t\t\treturn;\n \t\t\t\t}\n\n \t\t\t\t_this2.preserveEnvironment = true;\n \t\t\t}\n\n \t\t\t// The \'after\' hook should only execute when there are not tests left and\n \t\t\t// when the \'after\' and \'finish\' tasks are the only tasks left to process\n \t\t\tif (hookName === "after" && hookOwner.unskippedTestsRun !== numberOfUnskippedTests(hookOwner) - 1 && (config.queue.length > 0 || ProcessingQueue.taskCount() > 2)) {\n \t\t\t\treturn;\n \t\t\t}\n\n \t\t\tconfig.current = _this2;\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\t_this2.pushFailure(hookName + " failed on " + _this2.testName + ": " + (error.message || error), extractStacktrace(error, 0));\n \t\t\t}\n \t\t};\n\n \t\treturn runHook;\n \t},\n\n\n \t// Currently only used for module level hooks, can be used to add global level ones\n \thooks: function hooks(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\n \t\t\tif (module.hooks[handler].length) {\n \t\t\t\tfor (var i = 0; i < module.hooks[handler].length; i++) {\n \t\t\t\t\thooks.push(test.queueHook(module.hooks[handler][i], handler, module));\n \t\t\t\t}\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\n \t\treturn hooks;\n \t},\n\n\n \tfinish: function finish() {\n \t\tconfig.current = this;\n\n \t\t// Release the test callback to ensure that anything referenced has been\n \t\t// released to be garbage collected.\n \t\tthis.callback = undefined;\n\n \t\tif (this.steps.length) {\n \t\t\tvar stepsList = this.steps.join(", ");\n \t\t\tthis.pushFailure("Expected assert.verifySteps() to be called before end of test " + ("after using assert.step(). Unverified steps: " + stepsList), this.stack);\n \t\t}\n\n \t\tif (config.requireExpects && this.expected === null) {\n \t\t\tthis.pushFailure("Expected number of assertions to be defined, but expect() was " + "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 " + this.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 " + "expect(0) to accept zero assertions.", this.stack);\n \t\t}\n\n \t\tvar i,\n \t\t module = this.module,\n \t\t moduleName = module.name,\n \t\t testName = this.testName,\n \t\t skipped = !!this.skip,\n \t\t todo = !!this.todo,\n \t\t bad = 0,\n \t\t storage = config.storage;\n\n \t\tthis.runtime = now() - this.started;\n\n \t\tconfig.stats.all += this.assertions.length;\n \t\tmodule.stats.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\tmodule.stats.bad++;\n \t\t\t}\n \t\t}\n\n \t\tnotifyTestsRan(module, skipped);\n\n \t\t// Store result when possible\n \t\tif (storage) {\n \t\t\tif (bad) {\n \t\t\t\tstorage.setItem("qunit-test-" + moduleName + "-" + testName, bad);\n \t\t\t} else {\n \t\t\t\tstorage.removeItem("qunit-test-" + moduleName + "-" + testName);\n \t\t\t}\n \t\t}\n\n \t\t// After emitting the js-reporters event we cleanup the assertion data to\n \t\t// avoid leaking it. It is not used by the legacy testDone callbacks.\n \t\temit("testEnd", this.testReport.end(true));\n \t\tthis.testReport.slimAssertions();\n \t\tvar test = this;\n\n \t\treturn runLoggingCallbacks("testDone", {\n \t\t\tname: testName,\n \t\t\tmodule: moduleName,\n \t\t\tskipped: skipped,\n \t\t\ttodo: todo,\n \t\t\tfailed: bad,\n \t\t\tpassed: this.assertions.length - bad,\n \t\t\ttotal: this.assertions.length,\n \t\t\truntime: skipped ? 0 : 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\t// generating stack trace is expensive, so using a getter will help defer this until we need it\n \t\t\tget source() {\n \t\t\t\treturn test.stack;\n \t\t\t}\n \t\t}).then(function () {\n \t\t\tif (module.testsRun === numberOfTests(module)) {\n \t\t\t\tvar completedModules = [module];\n\n \t\t\t\t// Check if the parent modules, iteratively, are done. If that the case,\n \t\t\t\t// we emit the `suiteEnd` event and trigger `moduleDone` callback.\n \t\t\t\tvar parent = module.parentModule;\n \t\t\t\twhile (parent && parent.testsRun === numberOfTests(parent)) {\n \t\t\t\t\tcompletedModules.push(parent);\n \t\t\t\t\tparent = parent.parentModule;\n \t\t\t\t}\n\n \t\t\t\treturn completedModules.reduce(function (promiseChain, completedModule) {\n \t\t\t\t\treturn promiseChain.then(function () {\n \t\t\t\t\t\treturn logSuiteEnd(completedModule);\n \t\t\t\t\t});\n \t\t\t\t}, Promise$1.resolve([]));\n \t\t\t}\n \t\t}).then(function () {\n \t\t\tconfig.current = undefined;\n \t\t});\n\n \t\tfunction logSuiteEnd(module) {\n\n \t\t\t// Reset `module.hooks` to ensure that anything referenced in these hooks\n \t\t\t// has been released to be garbage collected.\n \t\t\tmodule.hooks = {};\n\n \t\t\temit("suiteEnd", module.suiteReport.end(true));\n \t\t\treturn runLoggingCallbacks("moduleDone", {\n \t\t\t\tname: module.name,\n \t\t\t\ttests: module.tests,\n \t\t\t\tfailed: module.stats.bad,\n \t\t\t\tpassed: module.stats.all - module.stats.bad,\n \t\t\t\ttotal: module.stats.all,\n \t\t\t\truntime: now() - module.stats.started\n \t\t\t});\n \t\t}\n \t},\n\n \tpreserveTestEnvironment: function preserveTestEnvironment() {\n \t\tif (this.preserveEnvironment) {\n \t\t\tthis.module.testEnvironment = this.testEnvironment;\n \t\t\tthis.testEnvironment = extend({}, this.module.testEnvironment);\n \t\t}\n \t},\n\n \tqueue: function queue() {\n \t\tvar test = this;\n\n \t\tif (!this.valid()) {\n \t\t\treturn;\n \t\t}\n\n \t\tfunction runTest() {\n \t\t\treturn [function () {\n \t\t\t\treturn test.before();\n \t\t\t}].concat(toConsumableArray(test.hooks("before")), [function () {\n \t\t\t\ttest.preserveTestEnvironment();\n \t\t\t}], toConsumableArray(test.hooks("beforeEach")), [function () {\n \t\t\t\ttest.run();\n \t\t\t}], toConsumableArray(test.hooks("afterEach").reverse()), toConsumableArray(test.hooks("after").reverse()), [function () {\n \t\t\t\ttest.after();\n \t\t\t}, function () {\n \t\t\t\treturn test.finish();\n \t\t\t}]);\n \t\t}\n\n \t\tvar previousFailCount = config.storage && +config.storage.getItem("qunit-test-" + this.module.name + "-" + this.testName);\n\n \t\t// Prioritize previously failed tests, detected from storage\n \t\tvar prioritize = config.reorder && !!previousFailCount;\n\n \t\tthis.previousFailure = !!previousFailCount;\n\n \t\tProcessingQueue.add(runTest, prioritize, config.seed);\n\n \t\t// If the queue has already finished, we manually process the new test\n \t\tif (ProcessingQueue.finished) {\n \t\t\tProcessingQueue.advance();\n \t\t}\n \t},\n\n\n \tpushResult: function pushResult(resultInfo) {\n \t\tif (this !== config.current) {\n \t\t\tthrow new Error("Assertion occurred after test had finished.");\n \t\t}\n\n \t\t// Destructure of resultInfo = { result, actual, expected, message, negative }\n \t\tvar source,\n \t\t details = {\n \t\t\tmodule: this.module.name,\n \t\t\tname: this.testName,\n \t\t\tresult: resultInfo.result,\n \t\t\tmessage: resultInfo.message,\n \t\t\tactual: resultInfo.actual,\n \t\t\ttestId: this.testId,\n \t\t\tnegative: resultInfo.negative || false,\n \t\t\truntime: now() - this.started,\n \t\t\ttodo: !!this.todo\n \t\t};\n\n \t\tif (hasOwn.call(resultInfo, "expected")) {\n \t\t\tdetails.expected = resultInfo.expected;\n \t\t}\n\n \t\tif (!resultInfo.result) {\n \t\t\tsource = resultInfo.source || sourceFromStacktrace();\n\n \t\t\tif (source) {\n \t\t\t\tdetails.source = source;\n \t\t\t}\n \t\t}\n\n \t\tthis.logAssertion(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 pushFailure(message, source, actual) {\n \t\tif (!(this instanceof Test)) {\n \t\t\tthrow new Error("pushFailure() assertion outside test context, was " + sourceFromStacktrace(2));\n \t\t}\n\n \t\tthis.pushResult({\n \t\t\tresult: false,\n \t\t\tmessage: message || "error",\n \t\t\tactual: actual || null,\n \t\t\tsource: source\n \t\t});\n \t},\n\n \t/**\n * Log assertion details using both the old QUnit.log interface and\n * QUnit.on( "assertion" ) interface.\n *\n * @private\n */\n \tlogAssertion: function logAssertion(details) {\n \t\trunLoggingCallbacks("log", details);\n\n \t\tvar assertion = {\n \t\t\tpassed: details.result,\n \t\t\tactual: details.actual,\n \t\t\texpected: details.expected,\n \t\t\tmessage: details.message,\n \t\t\tstack: details.source,\n \t\t\ttodo: details.todo\n \t\t};\n \t\tthis.testReport.pushAssertion(assertion);\n \t\temit("assertion", assertion);\n \t},\n\n\n \tresolvePromise: function resolvePromise(promise, phase) {\n \t\tvar then,\n \t\t resume,\n \t\t message,\n \t\t test = this;\n \t\tif (promise != null) {\n \t\t\tthen = promise.then;\n \t\t\tif (objectType(then) === "function") {\n \t\t\t\tresume = internalStop(test);\n \t\t\t\tif (config.notrycatch) {\n \t\t\t\t\tthen.call(promise, function () {\n \t\t\t\t\t\tresume();\n \t\t\t\t\t});\n \t\t\t\t} else {\n \t\t\t\t\tthen.call(promise, function () {\n \t\t\t\t\t\tresume();\n \t\t\t\t\t}, function (error) {\n \t\t\t\t\t\tmessage = "Promise rejected " + (!phase ? "during" : phase.replace(/Each$/, "")) + " \\"" + test.testName + "\\": " + (error && 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\tinternalRecover(test);\n \t\t\t\t\t});\n \t\t\t\t}\n \t\t\t}\n \t\t}\n \t},\n\n \tvalid: function valid() {\n \t\tvar filter = config.filter,\n \t\t regexFilter = /^(!?)\\/([\\w\\W]*)\\/(i?$)/.exec(filter),\n \t\t module = config.module && config.module.toLowerCase(),\n \t\t fullName = 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) || testModule.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 && !moduleChainIdMatch(this.module)) {\n\n \t\t\treturn false;\n \t\t}\n\n \t\tif (config.testId && config.testId.length > 0 && !inArray(this.testId, config.testId)) {\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 ? this.regexFilter(!!regexFilter[1], regexFilter[2], regexFilter[3], fullName) : this.stringFilter(filter, fullName);\n \t},\n\n \tregexFilter: function regexFilter(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 stringFilter(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 function pushFailure() {\n \tif (!config.current) {\n \t\tthrow new Error("pushFailure() assertion outside test context, in " + sourceFromStacktrace(2));\n \t}\n\n \t// Gets current test obj\n \tvar currentTest = config.current;\n\n \treturn currentTest.pushFailure.apply(currentTest, arguments);\n }\n\n function saveGlobal() {\n \tconfig.pollution = [];\n\n \tif (config.noglobals) {\n \t\tfor (var key in global$1) {\n \t\t\tif (hasOwn.call(global$1, 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\n function checkPollution() {\n \tvar newGlobals,\n \t deletedGlobals,\n \t old = config.pollution;\n\n \tsaveGlobal();\n\n \tnewGlobals = diff(config.pollution, old);\n \tif (newGlobals.length > 0) {\n \t\tpushFailure("Introduced global variable(s): " + newGlobals.join(", "));\n \t}\n\n \tdeletedGlobals = diff(old, config.pollution);\n \tif (deletedGlobals.length > 0) {\n \t\tpushFailure("Deleted global variable(s): " + deletedGlobals.join(", "));\n \t}\n }\n\n // Will be exposed as QUnit.test\n function test(testName, callback) {\n \tif (focused$1) {\n \t\treturn;\n \t}\n\n \tvar newTest = new Test({\n \t\ttestName: testName,\n \t\tcallback: callback\n \t});\n\n \tnewTest.queue();\n }\n\n function todo(testName, callback) {\n \tif (focused$1) {\n \t\treturn;\n \t}\n\n \tvar newTest = new Test({\n \t\ttestName: testName,\n \t\tcallback: callback,\n \t\ttodo: true\n \t});\n\n \tnewTest.queue();\n }\n\n // Will be exposed as QUnit.skip\n function skip(testName) {\n \tif (focused$1) {\n \t\treturn;\n \t}\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\n function only(testName, callback) {\n \tif (!focused$1) {\n \t\tconfig.queue.length = 0;\n \t\tfocused$1 = true;\n \t}\n\n \tvar newTest = new Test({\n \t\ttestName: testName,\n \t\tcallback: callback\n \t});\n\n \tnewTest.queue();\n }\n\n // Resets config.timeout with a new timeout duration.\n function resetTestTimeout(timeoutDuration) {\n \tclearTimeout(config.timeout);\n \tconfig.timeout = setTimeout$1(config.timeoutHandler(timeoutDuration), timeoutDuration);\n }\n\n // Put a hold on processing and return a function that will release it.\n function internalStop(test) {\n \tvar released = false;\n \ttest.semaphore += 1;\n \tconfig.blocking = true;\n\n \t// Set a recovery timeout, if so configured.\n \tif (defined.setTimeout) {\n \t\tvar timeoutDuration = void 0;\n\n \t\tif (typeof test.timeout === "number") {\n \t\t\ttimeoutDuration = test.timeout;\n \t\t} else if (typeof config.testTimeout === "number") {\n \t\t\ttimeoutDuration = config.testTimeout;\n \t\t}\n\n \t\tif (typeof timeoutDuration === "number" && timeoutDuration > 0) {\n \t\t\tclearTimeout(config.timeout);\n \t\t\tconfig.timeoutHandler = function (timeout) {\n \t\t\t\treturn function () {\n \t\t\t\t\tpushFailure("Test took longer than " + timeout + "ms; test timed out.", sourceFromStacktrace(2));\n \t\t\t\t\treleased = true;\n \t\t\t\t\tinternalRecover(test);\n \t\t\t\t};\n \t\t\t};\n \t\t\tconfig.timeout = setTimeout$1(config.timeoutHandler(timeoutDuration), timeoutDuration);\n \t\t}\n \t}\n\n \treturn function resume() {\n \t\tif (released) {\n \t\t\treturn;\n \t\t}\n\n \t\treleased = true;\n \t\ttest.semaphore -= 1;\n \t\tinternalStart(test);\n \t};\n }\n\n // Forcefully release all processing holds.\n function internalRecover(test) {\n \ttest.semaphore = 0;\n \tinternalStart(test);\n }\n\n // Release a processing hold, scheduling a resumption attempt if no holds remain.\n function internalStart(test) {\n\n \t// If semaphore is non-numeric, throw error\n \tif (isNaN(test.semaphore)) {\n \t\ttest.semaphore = 0;\n\n \t\tpushFailure("Invalid value on test.semaphore", sourceFromStacktrace(2));\n \t\treturn;\n \t}\n\n \t// Don\'t start until equal number of stop-calls\n \tif (test.semaphore > 0) {\n \t\treturn;\n \t}\n\n \t// Throw an Error if start is called more often than stop\n \tif (test.semaphore < 0) {\n \t\ttest.semaphore = 0;\n\n \t\tpushFailure("Tried to restart test while already started (test\'s semaphore was 0 already)", sourceFromStacktrace(2));\n \t\treturn;\n \t}\n\n \t// Add a slight delay to allow more assertions etc.\n \tif (defined.setTimeout) {\n \t\tif (config.timeout) {\n \t\t\tclearTimeout(config.timeout);\n \t\t}\n \t\tconfig.timeout = setTimeout$1(function () {\n \t\t\tif (test.semaphore > 0) {\n \t\t\t\treturn;\n \t\t\t}\n\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});\n \t} else {\n \t\tbegin();\n \t}\n }\n\n function collectTests(module) {\n \tvar tests = [].concat(module.tests);\n \tvar modules = [].concat(toConsumableArray(module.childModules));\n\n \t// Do a breadth-first traversal of the child modules\n \twhile (modules.length) {\n \t\tvar nextModule = modules.shift();\n \t\ttests.push.apply(tests, nextModule.tests);\n \t\tmodules.push.apply(modules, toConsumableArray(nextModule.childModules));\n \t}\n\n \treturn tests;\n }\n\n function numberOfTests(module) {\n \treturn collectTests(module).length;\n }\n\n function numberOfUnskippedTests(module) {\n \treturn collectTests(module).filter(function (test) {\n \t\treturn !test.skip;\n \t}).length;\n }\n\n function notifyTestsRan(module, skipped) {\n \tmodule.testsRun++;\n \tif (!skipped) {\n \t\tmodule.unskippedTestsRun++;\n \t}\n \twhile (module = module.parentModule) {\n \t\tmodule.testsRun++;\n \t\tif (!skipped) {\n \t\t\tmodule.unskippedTestsRun++;\n \t\t}\n \t}\n }\n\n var Assert = function () {\n \tfunction Assert(testContext) {\n \t\tclassCallCheck(this, Assert);\n\n \t\tthis.test = testContext;\n \t}\n\n \t// Assert helpers\n\n \tcreateClass(Assert, [{\n \t\tkey: "timeout",\n \t\tvalue: function timeout(duration) {\n \t\t\tif (typeof duration !== "number") {\n \t\t\t\tthrow new Error("You must pass a number as the duration to assert.timeout");\n \t\t\t}\n\n \t\t\tthis.test.timeout = duration;\n\n \t\t\t// If a timeout has been set, clear it and reset with the new duration\n \t\t\tif (config.timeout) {\n \t\t\t\tclearTimeout(config.timeout);\n\n \t\t\t\tif (config.timeoutHandler && this.test.timeout > 0) {\n \t\t\t\t\tresetTestTimeout(this.test.timeout);\n \t\t\t\t}\n \t\t\t}\n \t\t}\n\n \t\t// Documents a "step", which is a string value, in a test as a passing assertion\n\n \t}, {\n \t\tkey: "step",\n \t\tvalue: function step(message) {\n \t\t\tvar assertionMessage = message;\n \t\t\tvar result = !!message;\n\n \t\t\tthis.test.steps.push(message);\n\n \t\t\tif (objectType(message) === "undefined" || message === "") {\n \t\t\t\tassertionMessage = "You must provide a message to assert.step";\n \t\t\t} else if (objectType(message) !== "string") {\n \t\t\t\tassertionMessage = "You must provide a string value to assert.step";\n \t\t\t\tresult = false;\n \t\t\t}\n\n \t\t\tthis.pushResult({\n \t\t\t\tresult: result,\n \t\t\t\tmessage: assertionMessage\n \t\t\t});\n \t\t}\n\n \t\t// Verifies the steps in a test match a given array of string values\n\n \t}, {\n \t\tkey: "verifySteps",\n \t\tvalue: function verifySteps(steps, message) {\n\n \t\t\t// Since the steps array is just string values, we can clone with slice\n \t\t\tvar actualStepsClone = this.test.steps.slice();\n \t\t\tthis.deepEqual(actualStepsClone, steps, message);\n \t\t\tthis.test.steps.length = 0;\n \t\t}\n\n \t\t// Specify the number of expected assertions to guarantee that failed test\n \t\t// (no assertions are run at all) don\'t slip through.\n\n \t}, {\n \t\tkey: "expect",\n \t\tvalue: function expect(asserts) {\n \t\t\tif (arguments.length === 1) {\n \t\t\t\tthis.test.expected = asserts;\n \t\t\t} else {\n \t\t\t\treturn this.test.expected;\n \t\t\t}\n \t\t}\n\n \t\t// Put a hold on processing and return a function that will release it a maximum of once.\n\n \t}, {\n \t\tkey: "async",\n \t\tvalue: function async(count) {\n \t\t\tvar test$$1 = this.test;\n\n \t\t\tvar popped = false,\n \t\t\t acceptCallCount = count;\n\n \t\t\tif (typeof acceptCallCount === "undefined") {\n \t\t\t\tacceptCallCount = 1;\n \t\t\t}\n\n \t\t\tvar resume = internalStop(test$$1);\n\n \t\t\treturn function done() {\n \t\t\t\tif (config.current !== test$$1) {\n \t\t\t\t\tthrow Error("assert.async callback called after test finished.");\n \t\t\t\t}\n\n \t\t\t\tif (popped) {\n \t\t\t\t\ttest$$1.pushFailure("Too many calls to the `assert.async` callback", sourceFromStacktrace(2));\n \t\t\t\t\treturn;\n \t\t\t\t}\n\n \t\t\t\tacceptCallCount -= 1;\n \t\t\t\tif (acceptCallCount > 0) {\n \t\t\t\t\treturn;\n \t\t\t\t}\n\n \t\t\t\tpopped = true;\n \t\t\t\tresume();\n \t\t\t};\n \t\t}\n\n \t\t// Exports test.push() to the user API\n \t\t// Alias of pushResult.\n\n \t}, {\n \t\tkey: "push",\n \t\tvalue: function push(result, actual, expected, message, negative) {\n \t\t\tLogger.warn("assert.push is deprecated and will be removed in QUnit 3.0." + " Please use assert.pushResult instead (https://api.qunitjs.com/assert/pushResult).");\n\n \t\t\tvar currentAssert = this instanceof Assert ? this : config.current.assert;\n \t\t\treturn currentAssert.pushResult({\n \t\t\t\tresult: result,\n \t\t\t\tactual: actual,\n \t\t\t\texpected: expected,\n \t\t\t\tmessage: message,\n \t\t\t\tnegative: negative\n \t\t\t});\n \t\t}\n \t}, {\n \t\tkey: "pushResult",\n \t\tvalue: function pushResult(resultInfo) {\n\n \t\t\t// Destructure of resultInfo = { result, actual, expected, message, negative }\n \t\t\tvar assert = this;\n \t\t\tvar currentTest = assert instanceof Assert && assert.test || config.current;\n\n \t\t\t// Backwards compatibility fix.\n \t\t\t// Allows the direct use of global exported assertions and QUnit.assert.*\n \t\t\t// Although, it\'s use is not recommended as it can leak assertions\n \t\t\t// to other tests from async tests, because we only get a reference to the current test,\n \t\t\t// not exactly the test where assertion were intended to be called.\n \t\t\tif (!currentTest) {\n \t\t\t\tthrow new Error("assertion outside test context, in " + sourceFromStacktrace(2));\n \t\t\t}\n\n \t\t\tif (!(assert instanceof Assert)) {\n \t\t\t\tassert = currentTest.assert;\n \t\t\t}\n\n \t\t\treturn assert.test.pushResult(resultInfo);\n \t\t}\n \t}, {\n \t\tkey: "ok",\n \t\tvalue: function ok(result, message) {\n \t\t\tif (!message) {\n \t\t\t\tmessage = result ? "okay" : "failed, expected argument to be truthy, was: " + dump.parse(result);\n \t\t\t}\n\n \t\t\tthis.pushResult({\n \t\t\t\tresult: !!result,\n \t\t\t\tactual: result,\n \t\t\t\texpected: true,\n \t\t\t\tmessage: message\n \t\t\t});\n \t\t}\n \t}, {\n \t\tkey: "notOk",\n \t\tvalue: function notOk(result, message) {\n \t\t\tif (!message) {\n \t\t\t\tmessage = !result ? "okay" : "failed, expected argument to be falsy, was: " + dump.parse(result);\n \t\t\t}\n\n \t\t\tthis.pushResult({\n \t\t\t\tresult: !result,\n \t\t\t\tactual: result,\n \t\t\t\texpected: false,\n \t\t\t\tmessage: message\n \t\t\t});\n \t\t}\n \t}, {\n \t\tkey: "equal",\n \t\tvalue: function equal(actual, expected, message) {\n\n \t\t\t// eslint-disable-next-line eqeqeq\n \t\t\tvar result = expected == actual;\n\n \t\t\tthis.pushResult({\n \t\t\t\tresult: result,\n \t\t\t\tactual: actual,\n \t\t\t\texpected: expected,\n \t\t\t\tmessage: message\n \t\t\t});\n \t\t}\n \t}, {\n \t\tkey: "notEqual",\n \t\tvalue: function notEqual(actual, expected, message) {\n\n \t\t\t// eslint-disable-next-line eqeqeq\n \t\t\tvar result = expected != actual;\n\n \t\t\tthis.pushResult({\n \t\t\t\tresult: result,\n \t\t\t\tactual: actual,\n \t\t\t\texpected: expected,\n \t\t\t\tmessage: message,\n \t\t\t\tnegative: true\n \t\t\t});\n \t\t}\n \t}, {\n \t\tkey: "propEqual",\n \t\tvalue: function propEqual(actual, expected, message) {\n \t\t\tactual = objectValues(actual);\n \t\t\texpected = objectValues(expected);\n\n \t\t\tthis.pushResult({\n \t\t\t\tresult: equiv(actual, expected),\n \t\t\t\tactual: actual,\n \t\t\t\texpected: expected,\n \t\t\t\tmessage: message\n \t\t\t});\n \t\t}\n \t}, {\n \t\tkey: "notPropEqual",\n \t\tvalue: function notPropEqual(actual, expected, message) {\n \t\t\tactual = objectValues(actual);\n \t\t\texpected = objectValues(expected);\n\n \t\t\tthis.pushResult({\n \t\t\t\tresult: !equiv(actual, expected),\n \t\t\t\tactual: actual,\n \t\t\t\texpected: expected,\n \t\t\t\tmessage: message,\n \t\t\t\tnegative: true\n \t\t\t});\n \t\t}\n \t}, {\n \t\tkey: "deepEqual",\n \t\tvalue: function deepEqual(actual, expected, message) {\n \t\t\tthis.pushResult({\n \t\t\t\tresult: equiv(actual, expected),\n \t\t\t\tactual: actual,\n \t\t\t\texpected: expected,\n \t\t\t\tmessage: message\n \t\t\t});\n \t\t}\n \t}, {\n \t\tkey: "notDeepEqual",\n \t\tvalue: function notDeepEqual(actual, expected, message) {\n \t\t\tthis.pushResult({\n \t\t\t\tresult: !equiv(actual, expected),\n \t\t\t\tactual: actual,\n \t\t\t\texpected: expected,\n \t\t\t\tmessage: message,\n \t\t\t\tnegative: true\n \t\t\t});\n \t\t}\n \t}, {\n \t\tkey: "strictEqual",\n \t\tvalue: function strictEqual(actual, expected, message) {\n \t\t\tthis.pushResult({\n \t\t\t\tresult: expected === actual,\n \t\t\t\tactual: actual,\n \t\t\t\texpected: expected,\n \t\t\t\tmessage: message\n \t\t\t});\n \t\t}\n \t}, {\n \t\tkey: "notStrictEqual",\n \t\tvalue: function notStrictEqual(actual, expected, message) {\n \t\t\tthis.pushResult({\n \t\t\t\tresult: expected !== actual,\n \t\t\t\tactual: actual,\n \t\t\t\texpected: expected,\n \t\t\t\tmessage: message,\n \t\t\t\tnegative: true\n \t\t\t});\n \t\t}\n \t}, {\n \t\tkey: "throws",\n \t\tvalue: function throws(block, expected, message) {\n \t\t\tvar actual = void 0,\n \t\t\t result = false;\n\n \t\t\tvar currentTest = this instanceof Assert && this.test || config.current;\n\n \t\t\t// \'expected\' is optional unless doing string comparison\n \t\t\tif (objectType(expected) === "string") {\n \t\t\t\tif (message == null) {\n \t\t\t\t\tmessage = expected;\n \t\t\t\t\texpected = null;\n \t\t\t\t} else {\n \t\t\t\t\tthrow 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.");\n \t\t\t\t}\n \t\t\t}\n\n \t\t\tcurrentTest.ignoreGlobalErrors = true;\n \t\t\ttry {\n \t\t\t\tblock.call(currentTest.testEnvironment);\n \t\t\t} catch (e) {\n \t\t\t\tactual = e;\n \t\t\t}\n \t\t\tcurrentTest.ignoreGlobalErrors = false;\n\n \t\t\tif (actual) {\n \t\t\t\tvar expectedType = objectType(expected);\n\n \t\t\t\t// We don\'t want to validate thrown error\n \t\t\t\tif (!expected) {\n \t\t\t\t\tresult = true;\n\n \t\t\t\t\t// Expected is a regexp\n \t\t\t\t} else if (expectedType === "regexp") {\n \t\t\t\t\tresult = expected.test(errorString(actual));\n\n \t\t\t\t\t// Log the string form of the regexp\n \t\t\t\t\texpected = String(expected);\n\n \t\t\t\t\t// Expected is a constructor, maybe an Error constructor\n \t\t\t\t} else if (expectedType === "function" && actual instanceof expected) {\n \t\t\t\t\tresult = true;\n\n \t\t\t\t\t// Expected is an Error object\n \t\t\t\t} else if (expectedType === "object") {\n \t\t\t\t\tresult = actual instanceof expected.constructor && actual.name === expected.name && actual.message === expected.message;\n\n \t\t\t\t\t// Log the string form of the Error object\n \t\t\t\t\texpected = errorString(expected);\n\n \t\t\t\t\t// Expected is a validation function which returns true if validation passed\n \t\t\t\t} else if (expectedType === "function" && expected.call({}, actual) === true) {\n \t\t\t\t\texpected = null;\n \t\t\t\t\tresult = true;\n \t\t\t\t}\n \t\t\t}\n\n \t\t\tcurrentTest.assert.pushResult({\n \t\t\t\tresult: result,\n\n \t\t\t\t// undefined if it didn\'t throw\n \t\t\t\tactual: actual && errorString(actual),\n \t\t\t\texpected: expected,\n \t\t\t\tmessage: message\n \t\t\t});\n \t\t}\n \t}, {\n \t\tkey: "rejects",\n \t\tvalue: function rejects(promise, expected, message) {\n \t\t\tvar result = false;\n\n \t\t\tvar currentTest = this instanceof Assert && this.test || config.current;\n\n \t\t\t// \'expected\' is optional unless doing string comparison\n \t\t\tif (objectType(expected) === "string") {\n \t\t\t\tif (message === undefined) {\n \t\t\t\t\tmessage = expected;\n \t\t\t\t\texpected = undefined;\n \t\t\t\t} else {\n \t\t\t\t\tmessage = "assert.rejects does not accept a string value for the expected " + "argument.\\nUse a non-string object value (e.g. validator function) instead " + "if necessary.";\n\n \t\t\t\t\tcurrentTest.assert.pushResult({\n \t\t\t\t\t\tresult: false,\n \t\t\t\t\t\tmessage: message\n \t\t\t\t\t});\n\n \t\t\t\t\treturn;\n \t\t\t\t}\n \t\t\t}\n\n \t\t\tvar then = promise && promise.then;\n \t\t\tif (objectType(then) !== "function") {\n \t\t\t\tvar _message = "The value provided to `assert.rejects` in " + "\\"" + currentTest.testName + "\\" was not a promise.";\n\n \t\t\t\tcurrentTest.assert.pushResult({\n \t\t\t\t\tresult: false,\n \t\t\t\t\tmessage: _message,\n \t\t\t\t\tactual: promise\n \t\t\t\t});\n\n \t\t\t\treturn;\n \t\t\t}\n\n \t\t\tvar done = this.async();\n\n \t\t\treturn then.call(promise, function handleFulfillment() {\n \t\t\t\tvar message = "The promise returned by the `assert.rejects` callback in " + "\\"" + currentTest.testName + "\\" did not reject.";\n\n \t\t\t\tcurrentTest.assert.pushResult({\n \t\t\t\t\tresult: false,\n \t\t\t\t\tmessage: message,\n \t\t\t\t\tactual: promise\n \t\t\t\t});\n\n \t\t\t\tdone();\n \t\t\t}, function handleRejection(actual) {\n \t\t\t\tvar expectedType = objectType(expected);\n\n \t\t\t\t// We don\'t want to validate\n \t\t\t\tif (expected === undefined) {\n \t\t\t\t\tresult = true;\n\n \t\t\t\t\t// Expected is a regexp\n \t\t\t\t} else if (expectedType === "regexp") {\n \t\t\t\t\tresult = expected.test(errorString(actual));\n\n \t\t\t\t\t// Log the string form of the regexp\n \t\t\t\t\texpected = String(expected);\n\n \t\t\t\t\t// Expected is a constructor, maybe an Error constructor\n \t\t\t\t} else if (expectedType === "function" && actual instanceof expected) {\n \t\t\t\t\tresult = true;\n\n \t\t\t\t\t// Expected is an Error object\n \t\t\t\t} else if (expectedType === "object") {\n \t\t\t\t\tresult = actual instanceof expected.constructor && actual.name === expected.name && actual.message === expected.message;\n\n \t\t\t\t\t// Log the string form of the Error object\n \t\t\t\t\texpected = errorString(expected);\n\n \t\t\t\t\t// Expected is a validation function which returns true if validation passed\n \t\t\t\t} else {\n \t\t\t\t\tif (expectedType === "function") {\n \t\t\t\t\t\tresult = expected.call({}, actual) === true;\n \t\t\t\t\t\texpected = null;\n\n \t\t\t\t\t\t// Expected is some other invalid type\n \t\t\t\t\t} else {\n \t\t\t\t\t\tresult = false;\n \t\t\t\t\t\tmessage = "invalid expected value provided to `assert.rejects` " + "callback in \\"" + currentTest.testName + "\\": " + expectedType + ".";\n \t\t\t\t\t}\n \t\t\t\t}\n\n \t\t\t\tcurrentTest.assert.pushResult({\n \t\t\t\t\tresult: result,\n\n \t\t\t\t\t// leave rejection value of undefined as-is\n \t\t\t\t\tactual: actual && errorString(actual),\n \t\t\t\t\texpected: expected,\n \t\t\t\t\tmessage: message\n \t\t\t\t});\n\n \t\t\t\tdone();\n \t\t\t});\n \t\t}\n \t}]);\n \treturn Assert;\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 // eslint-disable-next-line dot-notation\n\n\n Assert.prototype.raises = Assert.prototype["throws"];\n\n /**\n * Converts an error into a simple string for comparisons.\n *\n * @param {Error|Object} error\n * @return {String}\n */\n function errorString(error) {\n \tvar resultErrorString = error.toString();\n\n \t// If the error wasn\'t a subclass of Error but something like\n \t// an object literal with name and message properties...\n \tif (resultErrorString.substring(0, 7) === "[object") {\n \t\tvar name = error.name ? error.name.toString() : "Error";\n \t\tvar message = error.message ? error.message.toString() : "";\n\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 /* global module, exports, define */\n function exportQUnit(QUnit) {\n\n \tif (defined.document) {\n\n \t\t// QUnit may be defined when it is preconfigured but then only QUnit and QUnit.config may be defined.\n \t\tif (window$1.QUnit && window$1.QUnit.version) {\n \t\t\tthrow new Error("QUnit has already been defined.");\n \t\t}\n\n \t\twindow$1.QUnit = QUnit;\n \t}\n\n \t// For nodejs\n \tif (typeof module !== "undefined" && module && module.exports) {\n \t\tmodule.exports = QUnit;\n\n \t\t// For consistency with CommonJS environments\' exports\n \t\tmodule.exports.QUnit = QUnit;\n \t}\n\n \t// For CommonJS with exports, but without module.exports, like Rhino\n \tif (typeof exports !== "undefined" && exports) {\n \t\texports.QUnit = QUnit;\n \t}\n\n \tif (typeof define === "function" && define.amd) {\n \t\tdefine(function () {\n \t\t\treturn QUnit;\n \t\t});\n \t\tQUnit.config.autostart = false;\n \t}\n\n \t// For Web/Service Workers\n \tif (self$1 && self$1.WorkerGlobalScope && self$1 instanceof self$1.WorkerGlobalScope) {\n \t\tself$1.QUnit = QUnit;\n \t}\n }\n\n // Handle an unhandled exception. By convention, returns true if further\n // error handling should be suppressed and false otherwise.\n // In this case, we will only suppress further error handling if the\n // "ignoreGlobalErrors" configuration option is enabled.\n function onError(error) {\n \tfor (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n \t\targs[_key - 1] = arguments[_key];\n \t}\n\n \tif (config.current) {\n \t\tif (config.current.ignoreGlobalErrors) {\n \t\t\treturn true;\n \t\t}\n \t\tpushFailure.apply(undefined, [error.message, error.stacktrace || error.fileName + ":" + error.lineNumber].concat(args));\n \t} else {\n \t\ttest("global failure", extend(function () {\n \t\t\tpushFailure.apply(undefined, [error.message, error.stacktrace || error.fileName + ":" + error.lineNumber].concat(args));\n \t\t}, { validTest: true }));\n \t}\n\n \treturn false;\n }\n\n // Handle an unhandled rejection\n function onUnhandledRejection(reason) {\n \tvar resultInfo = {\n \t\tresult: false,\n \t\tmessage: reason.message || "error",\n \t\tactual: reason,\n \t\tsource: reason.stack || sourceFromStacktrace(3)\n \t};\n\n \tvar currentTest = config.current;\n \tif (currentTest) {\n \t\tcurrentTest.assert.pushResult(resultInfo);\n \t} else {\n \t\ttest("global failure", extend(function (assert) {\n \t\t\tassert.pushResult(resultInfo);\n \t\t}, { validTest: true }));\n \t}\n }\n\n var QUnit = {};\n var globalSuite = new SuiteReport();\n\n // The initial "currentModule" represents the global (or top-level) module that\n // is not explicitly defined by the user, therefore we add the "globalSuite" to\n // it since each module has a suiteReport associated with it.\n config.currentModule.suiteReport = globalSuite;\n\n var globalStartCalled = false;\n var runStarted = false;\n\n // Figure out if we\'re running the tests from a server or not\n QUnit.isLocal = !(defined.document && window$1.location.protocol !== "file:");\n\n // Expose the current QUnit version\n QUnit.version = "2.10.0";\n\n extend(QUnit, {\n \ton: on,\n\n \tmodule: module$1,\n\n \ttest: test,\n\n \ttodo: todo,\n\n \tskip: skip,\n\n \tonly: only,\n\n \tstart: function start(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() while test already started running");\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 " + "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 we set autostart and then\n \t\t\t\t// load if we\'re in Node or wait for the browser\'s load event.\n \t\t\t\tconfig.autostart = true;\n\n \t\t\t\t// Starts from Node even if .load was not previously called. We still return\n \t\t\t\t// early otherwise we\'ll wind up "beginning" twice.\n \t\t\t\tif (!defined.document) {\n \t\t\t\t\tQUnit.load();\n \t\t\t\t}\n\n \t\t\t\treturn;\n \t\t\t}\n \t\t} else {\n \t\t\tthrow new Error("QUnit.start cannot be called inside a test context.");\n \t\t}\n\n \t\tscheduleBegin();\n \t},\n\n \tconfig: config,\n\n \tis: is,\n\n \tobjectType: objectType,\n\n \textend: extend,\n\n \tload: function load() {\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\tstarted: 0,\n \t\t\tupdateRate: 1000,\n \t\t\tautostart: true,\n \t\t\tfilter: ""\n \t\t}, true);\n\n \t\tif (!runStarted) {\n \t\t\tconfig.blocking = false;\n\n \t\t\tif (config.autostart) {\n \t\t\t\tscheduleBegin();\n \t\t\t}\n \t\t}\n \t},\n\n \tstack: function stack(offset) {\n \t\toffset = (offset || 0) + 2;\n \t\treturn sourceFromStacktrace(offset);\n \t},\n\n \tonError: onError,\n\n \tonUnhandledRejection: onUnhandledRejection\n });\n\n QUnit.pushFailure = pushFailure;\n QUnit.assert = Assert.prototype;\n QUnit.equiv = equiv;\n QUnit.dump = dump;\n\n registerLoggingCallbacks(QUnit);\n\n function scheduleBegin() {\n\n \trunStarted = true;\n\n \t// Add a slight delay to allow definition of more modules and tests.\n \tif (defined.setTimeout) {\n \t\tsetTimeout$1(function () {\n \t\t\tbegin();\n \t\t});\n \t} else {\n \t\tbegin();\n \t}\n }\n\n function unblockAndAdvanceQueue() {\n \tconfig.blocking = false;\n \tProcessingQueue.advance();\n }\n\n function begin() {\n \tvar i,\n \t l,\n \t modulesLog = [];\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\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\temit("runStart", globalSuite.start(true));\n \t\trunLoggingCallbacks("begin", {\n \t\t\ttotalTests: Test.count,\n \t\t\tmodules: modulesLog\n \t\t}).then(unblockAndAdvanceQueue);\n \t} else {\n \t\tunblockAndAdvanceQueue();\n \t}\n }\n\n exportQUnit(QUnit);\n\n (function () {\n\n \tif (typeof window$1 === "undefined" || typeof document$1 === "undefined") {\n \t\treturn;\n \t}\n\n \tvar config = QUnit.config,\n \t hasOwn = Object.prototype.hasOwnProperty;\n\n \t// Stores fixture HTML for resetting later\n \tfunction storeFixture() {\n\n \t\t// Avoid overwriting user-defined values\n \t\tif (hasOwn.call(config, "fixture")) {\n \t\t\treturn;\n \t\t}\n\n \t\tvar fixture = document$1.getElementById("qunit-fixture");\n \t\tif (fixture) {\n \t\t\tconfig.fixture = fixture.cloneNode(true);\n \t\t}\n \t}\n\n \tQUnit.begin(storeFixture);\n\n \t// Resets the fixture DOM element if available.\n \tfunction resetFixture() {\n \t\tif (config.fixture == null) {\n \t\t\treturn;\n \t\t}\n\n \t\tvar fixture = document$1.getElementById("qunit-fixture");\n \t\tvar resetFixtureType = _typeof(config.fixture);\n \t\tif (resetFixtureType === "string") {\n\n \t\t\t// support user defined values for `config.fixture`\n \t\t\tvar newFixture = document$1.createElement("div");\n \t\t\tnewFixture.setAttribute("id", "qunit-fixture");\n \t\t\tnewFixture.innerHTML = config.fixture;\n \t\t\tfixture.parentNode.replaceChild(newFixture, fixture);\n \t\t} else {\n \t\t\tvar clonedFixture = config.fixture.cloneNode(true);\n \t\t\tfixture.parentNode.replaceChild(clonedFixture, fixture);\n \t\t}\n \t}\n\n \tQUnit.testStart(resetFixture);\n })();\n\n (function () {\n\n \t// Only interact with URLs via window.location\n \tvar location = typeof window$1 !== "undefined" && window$1.location;\n \tif (!location) {\n \t\treturn;\n \t}\n\n \tvar urlParams = getUrlParams();\n\n \tQUnit.urlParams = urlParams;\n\n \t// Match module/test by inclusion in an array\n \tQUnit.config.moduleId = [].concat(urlParams.moduleId || []);\n \tQUnit.config.testId = [].concat(urlParams.testId || []);\n\n \t// Exact case-insensitive match of the module name\n \tQUnit.config.module = urlParams.module;\n\n \t// Regular expression or case-insenstive substring match against "moduleName: testName"\n \tQUnit.config.filter = urlParams.filter;\n\n \t// Test order randomization\n \tif (urlParams.seed === true) {\n\n \t\t// Generate a random seed if the option is specified without a value\n \t\tQUnit.config.seed = Math.random().toString(36).slice(2);\n \t} else if (urlParams.seed) {\n \t\tQUnit.config.seed = urlParams.seed;\n \t}\n\n \t// Add URL-parameter-mapped config values with UI form rendering data\n \tQUnit.config.urlConfig.push({\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\tid: "noglobals",\n \t\tlabel: "Check for Globals",\n \t\ttooltip: "Enabling this will test if any test introduces new properties on the " + "global object (`window` in Browsers). Stored as query-strings."\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 " + "exceptions in IE reasonable. Stored as query-strings."\n \t});\n\n \tQUnit.begin(function () {\n \t\tvar i,\n \t\t option,\n \t\t urlConfig = QUnit.config.urlConfig;\n\n \t\tfor (i = 0; i < urlConfig.length; i++) {\n\n \t\t\t// Options can be either strings or objects with nonempty "id" properties\n \t\t\toption = QUnit.config.urlConfig[i];\n \t\t\tif (typeof option !== "string") {\n \t\t\t\toption = option.id;\n \t\t\t}\n\n \t\t\tif (QUnit.config[option] === undefined) {\n \t\t\t\tQUnit.config[option] = urlParams[option];\n \t\t\t}\n \t\t}\n \t});\n\n \tfunction getUrlParams() {\n \t\tvar i, param, name, value;\n \t\tvar urlParams = Object.create(null);\n \t\tvar params = location.search.slice(1).split("&");\n \t\tvar length = params.length;\n\n \t\tfor (i = 0; i < length; i++) {\n \t\t\tif (params[i]) {\n \t\t\t\tparam = params[i].split("=");\n \t\t\t\tname = decodeQueryParam(param[0]);\n\n \t\t\t\t// Allow just a key to turn on a flag, e.g., test.html?noglobals\n \t\t\t\tvalue = param.length === 1 || decodeQueryParam(param.slice(1).join("="));\n \t\t\t\tif (name in urlParams) {\n \t\t\t\t\turlParams[name] = [].concat(urlParams[name], value);\n \t\t\t\t} else {\n \t\t\t\t\turlParams[name] = value;\n \t\t\t\t}\n \t\t\t}\n \t\t}\n\n \t\treturn urlParams;\n \t}\n\n \tfunction decodeQueryParam(param) {\n \t\treturn decodeURIComponent(param.replace(/\\+/g, "%20"));\n \t}\n })();\n\n var stats = {\n \tpassedTests: 0,\n \tfailedTests: 0,\n \tskippedTests: 0,\n \ttodoTests: 0\n };\n\n // Escape text for attribute or text content.\n function 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\t\tcase "\'":\n \t\t\t\treturn "'";\n \t\t\tcase "\\"":\n \t\t\t\treturn """;\n \t\t\tcase "<":\n \t\t\t\treturn "<";\n \t\t\tcase ">":\n \t\t\t\treturn ">";\n \t\t\tcase "&":\n \t\t\t\treturn "&";\n \t\t}\n \t});\n }\n\n (function () {\n\n \t// Don\'t load the HTML Reporter on non-browser environments\n \tif (typeof window$1 === "undefined" || !window$1.document) {\n \t\treturn;\n \t}\n\n \tvar config = QUnit.config,\n \t hiddenTests = [],\n \t document = window$1.document,\n \t collapseNext = false,\n \t hasOwn$$1 = Object.prototype.hasOwnProperty,\n \t unfilteredUrl = setUrl({ filter: undefined, module: undefined,\n \t\tmoduleId: undefined, testId: undefined }),\n \t modulesList = [];\n\n \tfunction addEvent(elem, type, fn) {\n \t\telem.addEventListener(type, fn, false);\n \t}\n\n \tfunction removeEvent(elem, type, fn) {\n \t\telem.removeEventListener(type, fn, false);\n \t}\n\n \tfunction addEvents(elems, type, fn) {\n \t\tvar i = elems.length;\n \t\twhile (i--) {\n \t\t\taddEvent(elems[i], type, fn);\n \t\t}\n \t}\n\n \tfunction hasClass(elem, name) {\n \t\treturn (" " + elem.className + " ").indexOf(" " + name + " ") >= 0;\n \t}\n\n \tfunction addClass(elem, name) {\n \t\tif (!hasClass(elem, name)) {\n \t\t\telem.className += (elem.className ? " " : "") + name;\n \t\t}\n \t}\n\n \tfunction toggleClass(elem, name, force) {\n \t\tif (force || typeof force === "undefined" && !hasClass(elem, name)) {\n \t\t\taddClass(elem, name);\n \t\t} else {\n \t\t\tremoveClass(elem, name);\n \t\t}\n \t}\n\n \tfunction removeClass(elem, name) {\n \t\tvar set = " " + elem.className + " ";\n\n \t\t// Class name may appear multiple times\n \t\twhile (set.indexOf(" " + name + " ") >= 0) {\n \t\t\tset = set.replace(" " + name + " ", " ");\n \t\t}\n\n \t\t// Trim for prettiness\n \t\telem.className = typeof set.trim === "function" ? set.trim() : set.replace(/^\\s+|\\s+$/g, "");\n \t}\n\n \tfunction id(name) {\n \t\treturn document.getElementById && document.getElementById(name);\n \t}\n\n \tfunction abortTests() {\n \t\tvar abortButton = id("qunit-abort-tests-button");\n \t\tif (abortButton) {\n \t\t\tabortButton.disabled = true;\n \t\t\tabortButton.innerHTML = "Aborting...";\n \t\t}\n \t\tQUnit.config.queue.length = 0;\n \t\treturn false;\n \t}\n\n \tfunction interceptNavigation(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 \tfunction getUrlConfigHtml() {\n \t\tvar i,\n \t\t j,\n \t\t val,\n \t\t escaped,\n \t\t escapedTooltip,\n \t\t selection = false,\n \t\t urlConfig = config.urlConfig,\n \t\t urlConfigHtml = "";\n\n \t\tfor (i = 0; i < urlConfig.length; i++) {\n\n \t\t\t// Options can be either strings or objects with nonempty "id" properties\n \t\t\tval = config.urlConfig[i];\n \t\t\tif (typeof val === "string") {\n \t\t\t\tval = {\n \t\t\t\t\tid: val,\n \t\t\t\t\tlabel: val\n \t\t\t\t};\n \t\t\t}\n\n \t\t\tescaped = escapeText(val.id);\n \t\t\tescapedTooltip = escapeText(val.tooltip);\n\n \t\t\tif (!val.value || typeof val.value === "string") {\n \t\t\t\turlConfigHtml += "";\n \t\t\t} else {\n \t\t\t\turlConfigHtml += "";\n \t\t\t}\n \t\t}\n\n \t\treturn urlConfigHtml;\n \t}\n\n \t// Handle "click" events on toolbar checkboxes and "change" for select menus.\n \t// Updates the URL with the new state of `config.urlConfig` values.\n \tfunction toolbarChanged() {\n \t\tvar updatedUrl,\n \t\t value,\n \t\t tests,\n \t\t field = this,\n \t\t params = {};\n\n \t\t// Detect if field is a select menu or a checkbox\n \t\tif ("selectedIndex" in field) {\n \t\t\tvalue = field.options[field.selectedIndex].value || undefined;\n \t\t} else {\n \t\t\tvalue = field.checked ? field.defaultValue || true : undefined;\n \t\t}\n\n \t\tparams[field.name] = value;\n \t\tupdatedUrl = setUrl(params);\n\n \t\t// Check if we can apply the change without a page refresh\n \t\tif ("hidepassed" === field.name && "replaceState" in window$1.history) {\n \t\t\tQUnit.urlParams[field.name] = value;\n \t\t\tconfig[field.name] = value || false;\n \t\t\ttests = id("qunit-tests");\n \t\t\tif (tests) {\n \t\t\t\tvar length = tests.children.length;\n \t\t\t\tvar children = tests.children;\n\n \t\t\t\tif (field.checked) {\n \t\t\t\t\tfor (var i = 0; i < length; i++) {\n \t\t\t\t\t\tvar test$$1 = children[i];\n\n \t\t\t\t\t\tif (test$$1 && test$$1.className.indexOf("pass") > -1) {\n \t\t\t\t\t\t\thiddenTests.push(test$$1);\n \t\t\t\t\t\t}\n \t\t\t\t\t}\n\n \t\t\t\t\tvar _iteratorNormalCompletion = true;\n \t\t\t\t\tvar _didIteratorError = false;\n \t\t\t\t\tvar _iteratorError = undefined;\n\n \t\t\t\t\ttry {\n \t\t\t\t\t\tfor (var _iterator = hiddenTests[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n \t\t\t\t\t\t\tvar hiddenTest = _step.value;\n\n \t\t\t\t\t\t\ttests.removeChild(hiddenTest);\n \t\t\t\t\t\t}\n \t\t\t\t\t} catch (err) {\n \t\t\t\t\t\t_didIteratorError = true;\n \t\t\t\t\t\t_iteratorError = err;\n \t\t\t\t\t} finally {\n \t\t\t\t\t\ttry {\n \t\t\t\t\t\t\tif (!_iteratorNormalCompletion && _iterator.return) {\n \t\t\t\t\t\t\t\t_iterator.return();\n \t\t\t\t\t\t\t}\n \t\t\t\t\t\t} finally {\n \t\t\t\t\t\t\tif (_didIteratorError) {\n \t\t\t\t\t\t\t\tthrow _iteratorError;\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} else {\n \t\t\t\t\twhile ((test$$1 = hiddenTests.pop()) != null) {\n \t\t\t\t\t\ttests.appendChild(test$$1);\n \t\t\t\t\t}\n \t\t\t\t}\n \t\t\t}\n \t\t\twindow$1.history.replaceState(null, "", updatedUrl);\n \t\t} else {\n \t\t\twindow$1.location = updatedUrl;\n \t\t}\n \t}\n\n \tfunction setUrl(params) {\n \t\tvar key,\n \t\t arrValue,\n \t\t i,\n \t\t querystring = "?",\n \t\t location = window$1.location;\n\n \t\tparams = QUnit.extend(QUnit.extend({}, QUnit.urlParams), params);\n\n \t\tfor (key in params) {\n\n \t\t\t// Skip inherited or undefined properties\n \t\t\tif (hasOwn$$1.call(params, key) && params[key] !== undefined) {\n\n \t\t\t\t// Output a parameter for each value of this key\n \t\t\t\t// (but usually just one)\n \t\t\t\tarrValue = [].concat(params[key]);\n \t\t\t\tfor (i = 0; i < arrValue.length; i++) {\n \t\t\t\t\tquerystring += encodeURIComponent(key);\n \t\t\t\t\tif (arrValue[i] !== true) {\n \t\t\t\t\t\tquerystring += "=" + encodeURIComponent(arrValue[i]);\n \t\t\t\t\t}\n \t\t\t\t\tquerystring += "&";\n \t\t\t\t}\n \t\t\t}\n \t\t}\n \t\treturn location.protocol + "//" + location.host + location.pathname + querystring.slice(0, -1);\n \t}\n\n \tfunction applyUrlParams() {\n \t\tvar i,\n \t\t selectedModules = [],\n \t\t modulesList = id("qunit-modulefilter-dropdown-list").getElementsByTagName("input"),\n \t\t filter = id("qunit-filter-input").value;\n\n \t\tfor (i = 0; i < modulesList.length; i++) {\n \t\t\tif (modulesList[i].checked) {\n \t\t\t\tselectedModules.push(modulesList[i].value);\n \t\t\t}\n \t\t}\n\n \t\twindow$1.location = setUrl({\n \t\t\tfilter: filter === "" ? undefined : filter,\n \t\t\tmoduleId: selectedModules.length === 0 ? undefined : selectedModules,\n\n \t\t\t// Remove module and testId filter\n \t\t\tmodule: undefined,\n \t\t\ttestId: undefined\n \t\t});\n \t}\n\n \tfunction toolbarUrlConfigContainer() {\n \t\tvar urlConfigContainer = document.createElement("span");\n\n \t\turlConfigContainer.innerHTML = getUrlConfigHtml();\n \t\taddClass(urlConfigContainer, "qunit-url-config");\n\n \t\taddEvents(urlConfigContainer.getElementsByTagName("input"), "change", toolbarChanged);\n \t\taddEvents(urlConfigContainer.getElementsByTagName("select"), "change", toolbarChanged);\n\n \t\treturn urlConfigContainer;\n \t}\n\n \tfunction abortTestsButton() {\n \t\tvar button = document.createElement("button");\n \t\tbutton.id = "qunit-abort-tests-button";\n \t\tbutton.innerHTML = "Abort";\n \t\taddEvent(button, "click", abortTests);\n \t\treturn button;\n \t}\n\n \tfunction toolbarLooseFilter() {\n \t\tvar filter = document.createElement("form"),\n \t\t label = document.createElement("label"),\n \t\t input = document.createElement("input"),\n \t\t button = document.createElement("button");\n\n \t\taddClass(filter, "qunit-filter");\n\n \t\tlabel.innerHTML = "Filter: ";\n\n \t\tinput.type = "text";\n \t\tinput.value = config.filter || "";\n \t\tinput.name = "filter";\n \t\tinput.id = "qunit-filter-input";\n\n \t\tbutton.innerHTML = "Go";\n\n \t\tlabel.appendChild(input);\n\n \t\tfilter.appendChild(label);\n \t\tfilter.appendChild(document.createTextNode(" "));\n \t\tfilter.appendChild(button);\n \t\taddEvent(filter, "submit", interceptNavigation);\n\n \t\treturn filter;\n \t}\n\n \tfunction moduleListHtml() {\n \t\tvar i,\n \t\t checked,\n \t\t html = "";\n\n \t\tfor (i = 0; i < config.modules.length; i++) {\n \t\t\tif (config.modules[i].name !== "") {\n \t\t\t\tchecked = config.moduleId.indexOf(config.modules[i].moduleId) > -1;\n \t\t\t\thtml += "
  • ";\n \t\t\t}\n \t\t}\n\n \t\treturn html;\n \t}\n\n \tfunction toolbarModuleFilter() {\n \t\tvar commit,\n \t\t reset,\n \t\t moduleFilter = document.createElement("form"),\n \t\t label = document.createElement("label"),\n \t\t moduleSearch = document.createElement("input"),\n \t\t dropDown = document.createElement("div"),\n \t\t actions = document.createElement("span"),\n \t\t applyButton = document.createElement("button"),\n \t\t resetButton = document.createElement("button"),\n \t\t allModulesLabel = document.createElement("label"),\n \t\t allCheckbox = document.createElement("input"),\n \t\t dropDownList = document.createElement("ul"),\n \t\t dirty = false;\n\n \t\tmoduleSearch.id = "qunit-modulefilter-search";\n \t\tmoduleSearch.autocomplete = "off";\n \t\taddEvent(moduleSearch, "input", searchInput);\n \t\taddEvent(moduleSearch, "input", searchFocus);\n \t\taddEvent(moduleSearch, "focus", searchFocus);\n \t\taddEvent(moduleSearch, "click", searchFocus);\n\n \t\tlabel.id = "qunit-modulefilter-search-container";\n \t\tlabel.innerHTML = "Module: ";\n \t\tlabel.appendChild(moduleSearch);\n\n \t\tapplyButton.textContent = "Apply";\n \t\tapplyButton.style.display = "none";\n\n \t\tresetButton.textContent = "Reset";\n \t\tresetButton.type = "reset";\n \t\tresetButton.style.display = "none";\n\n \t\tallCheckbox.type = "checkbox";\n \t\tallCheckbox.checked = config.moduleId.length === 0;\n\n \t\tallModulesLabel.className = "clickable";\n \t\tif (config.moduleId.length) {\n \t\t\tallModulesLabel.className = "checked";\n \t\t}\n \t\tallModulesLabel.appendChild(allCheckbox);\n \t\tallModulesLabel.appendChild(document.createTextNode("All modules"));\n\n \t\tactions.id = "qunit-modulefilter-actions";\n \t\tactions.appendChild(applyButton);\n \t\tactions.appendChild(resetButton);\n \t\tactions.appendChild(allModulesLabel);\n \t\tcommit = actions.firstChild;\n \t\treset = commit.nextSibling;\n \t\taddEvent(commit, "click", applyUrlParams);\n\n \t\tdropDownList.id = "qunit-modulefilter-dropdown-list";\n \t\tdropDownList.innerHTML = moduleListHtml();\n\n \t\tdropDown.id = "qunit-modulefilter-dropdown";\n \t\tdropDown.style.display = "none";\n \t\tdropDown.appendChild(actions);\n \t\tdropDown.appendChild(dropDownList);\n \t\taddEvent(dropDown, "change", selectionChange);\n \t\tselectionChange();\n\n \t\tmoduleFilter.id = "qunit-modulefilter";\n \t\tmoduleFilter.appendChild(label);\n \t\tmoduleFilter.appendChild(dropDown);\n \t\taddEvent(moduleFilter, "submit", interceptNavigation);\n \t\taddEvent(moduleFilter, "reset", function () {\n\n \t\t\t// Let the reset happen, then update styles\n \t\t\twindow$1.setTimeout(selectionChange);\n \t\t});\n\n \t\t// Enables show/hide for the dropdown\n \t\tfunction searchFocus() {\n \t\t\tif (dropDown.style.display !== "none") {\n \t\t\t\treturn;\n \t\t\t}\n\n \t\t\tdropDown.style.display = "block";\n \t\t\taddEvent(document, "click", hideHandler);\n \t\t\taddEvent(document, "keydown", hideHandler);\n\n \t\t\t// Hide on Escape keydown or outside-container click\n \t\t\tfunction hideHandler(e) {\n \t\t\t\tvar inContainer = moduleFilter.contains(e.target);\n\n \t\t\t\tif (e.keyCode === 27 || !inContainer) {\n \t\t\t\t\tif (e.keyCode === 27 && inContainer) {\n \t\t\t\t\t\tmoduleSearch.focus();\n \t\t\t\t\t}\n \t\t\t\t\tdropDown.style.display = "none";\n \t\t\t\t\tremoveEvent(document, "click", hideHandler);\n \t\t\t\t\tremoveEvent(document, "keydown", hideHandler);\n \t\t\t\t\tmoduleSearch.value = "";\n \t\t\t\t\tsearchInput();\n \t\t\t\t}\n \t\t\t}\n \t\t}\n\n \t\t// Processes module search box input\n \t\tfunction searchInput() {\n \t\t\tvar i,\n \t\t\t item,\n \t\t\t searchText = moduleSearch.value.toLowerCase(),\n \t\t\t listItems = dropDownList.children;\n\n \t\t\tfor (i = 0; i < listItems.length; i++) {\n \t\t\t\titem = listItems[i];\n \t\t\t\tif (!searchText || item.textContent.toLowerCase().indexOf(searchText) > -1) {\n \t\t\t\t\titem.style.display = "";\n \t\t\t\t} else {\n \t\t\t\t\titem.style.display = "none";\n \t\t\t\t}\n \t\t\t}\n \t\t}\n\n \t\t// Processes selection changes\n \t\tfunction selectionChange(evt) {\n \t\t\tvar i,\n \t\t\t item,\n \t\t\t checkbox = evt && evt.target || allCheckbox,\n \t\t\t modulesList = dropDownList.getElementsByTagName("input"),\n \t\t\t selectedNames = [];\n\n \t\t\ttoggleClass(checkbox.parentNode, "checked", checkbox.checked);\n\n \t\t\tdirty = false;\n \t\t\tif (checkbox.checked && checkbox !== allCheckbox) {\n \t\t\t\tallCheckbox.checked = false;\n \t\t\t\tremoveClass(allCheckbox.parentNode, "checked");\n \t\t\t}\n \t\t\tfor (i = 0; i < modulesList.length; i++) {\n \t\t\t\titem = modulesList[i];\n \t\t\t\tif (!evt) {\n \t\t\t\t\ttoggleClass(item.parentNode, "checked", item.checked);\n \t\t\t\t} else if (checkbox === allCheckbox && checkbox.checked) {\n \t\t\t\t\titem.checked = false;\n \t\t\t\t\tremoveClass(item.parentNode, "checked");\n \t\t\t\t}\n \t\t\t\tdirty = dirty || item.checked !== item.defaultChecked;\n \t\t\t\tif (item.checked) {\n \t\t\t\t\tselectedNames.push(item.parentNode.textContent);\n \t\t\t\t}\n \t\t\t}\n\n \t\t\tcommit.style.display = reset.style.display = dirty ? "" : "none";\n \t\t\tmoduleSearch.placeholder = selectedNames.join(", ") || allCheckbox.parentNode.textContent;\n \t\t\tmoduleSearch.title = "Type to filter list. Current selection:\\n" + (selectedNames.join("\\n") || allCheckbox.parentNode.textContent);\n \t\t}\n\n \t\treturn moduleFilter;\n \t}\n\n \tfunction toolbarFilters() {\n \t\tvar toolbarFilters = document.createElement("span");\n\n \t\ttoolbarFilters.id = "qunit-toolbar-filters";\n \t\ttoolbarFilters.appendChild(toolbarLooseFilter());\n \t\ttoolbarFilters.appendChild(toolbarModuleFilter());\n\n \t\treturn toolbarFilters;\n \t}\n\n \tfunction appendToolbar() {\n \t\tvar toolbar = id("qunit-testrunner-toolbar");\n\n \t\tif (toolbar) {\n \t\t\ttoolbar.appendChild(toolbarUrlConfigContainer());\n \t\t\ttoolbar.appendChild(toolbarFilters());\n \t\t\ttoolbar.appendChild(document.createElement("div")).className = "clearfix";\n \t\t}\n \t}\n\n \tfunction appendHeader() {\n \t\tvar header = id("qunit-header");\n\n \t\tif (header) {\n \t\t\theader.innerHTML = "" + header.innerHTML + " ";\n \t\t}\n \t}\n\n \tfunction appendBanner() {\n \t\tvar banner = id("qunit-banner");\n\n \t\tif (banner) {\n \t\t\tbanner.className = "";\n \t\t}\n \t}\n\n \tfunction appendTestResults() {\n \t\tvar tests = id("qunit-tests"),\n \t\t result = id("qunit-testresult"),\n \t\t controls;\n\n \t\tif (result) {\n \t\t\tresult.parentNode.removeChild(result);\n \t\t}\n\n \t\tif (tests) {\n \t\t\ttests.innerHTML = "";\n \t\t\tresult = document.createElement("p");\n \t\t\tresult.id = "qunit-testresult";\n \t\t\tresult.className = "result";\n \t\t\ttests.parentNode.insertBefore(result, tests);\n \t\t\tresult.innerHTML = "
    Running...
     
    " + "
    " + "
    ";\n \t\t\tcontrols = id("qunit-testresult-controls");\n \t\t}\n\n \t\tif (controls) {\n \t\t\tcontrols.appendChild(abortTestsButton());\n \t\t}\n \t}\n\n \tfunction appendFilteredTest() {\n \t\tvar testId = QUnit.config.testId;\n \t\tif (!testId || testId.length <= 0) {\n \t\t\treturn "";\n \t\t}\n \t\treturn "
    Rerunning selected tests: " + escapeText(testId.join(", ")) + " Run all tests
    ";\n \t}\n\n \tfunction appendUserAgent() {\n \t\tvar userAgent = id("qunit-userAgent");\n\n \t\tif (userAgent) {\n \t\t\tuserAgent.innerHTML = "";\n \t\t\tuserAgent.appendChild(document.createTextNode("QUnit " + QUnit.version + "; " + navigator.userAgent));\n \t\t}\n \t}\n\n \tfunction appendInterface() {\n \t\tvar qunit = id("qunit");\n\n \t\tif (qunit) {\n \t\t\tqunit.innerHTML = "

    " + escapeText(document.title) + "

    " + "

    " + "
    " + appendFilteredTest() + "

    " + "
      ";\n \t\t}\n\n \t\tappendHeader();\n \t\tappendBanner();\n \t\tappendTestResults();\n \t\tappendUserAgent();\n \t\tappendToolbar();\n \t}\n\n \tfunction appendTest(name, testId, moduleName) {\n \t\tvar title,\n \t\t rerunTrigger,\n \t\t testBlock,\n \t\t assertList,\n \t\t tests = id("qunit-tests");\n\n \t\tif (!tests) {\n \t\t\treturn;\n \t\t}\n\n \t\ttitle = document.createElement("strong");\n \t\ttitle.innerHTML = getNameHtml(name, moduleName);\n\n \t\trerunTrigger = document.createElement("a");\n \t\trerunTrigger.innerHTML = "Rerun";\n \t\trerunTrigger.href = setUrl({ testId: testId });\n\n \t\ttestBlock = document.createElement("li");\n \t\ttestBlock.appendChild(title);\n \t\ttestBlock.appendChild(rerunTrigger);\n \t\ttestBlock.id = "qunit-test-output-" + testId;\n\n \t\tassertList = document.createElement("ol");\n \t\tassertList.className = "qunit-assert-list";\n\n \t\ttestBlock.appendChild(assertList);\n\n \t\ttests.appendChild(testBlock);\n \t}\n\n \t// HTML Reporter initialization and load\n \tQUnit.begin(function (details) {\n \t\tvar i, moduleObj;\n\n \t\t// Sort modules by name for the picker\n \t\tfor (i = 0; i < details.modules.length; i++) {\n \t\t\tmoduleObj = details.modules[i];\n \t\t\tif (moduleObj.name) {\n \t\t\t\tmodulesList.push(moduleObj.name);\n \t\t\t}\n \t\t}\n \t\tmodulesList.sort(function (a, b) {\n \t\t\treturn a.localeCompare(b);\n \t\t});\n\n \t\t// Initialize QUnit elements\n \t\tappendInterface();\n \t});\n\n \tQUnit.done(function (details) {\n \t\tvar banner = id("qunit-banner"),\n \t\t tests = id("qunit-tests"),\n \t\t abortButton = id("qunit-abort-tests-button"),\n \t\t totalTests = stats.passedTests + stats.skippedTests + stats.todoTests + stats.failedTests,\n \t\t 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(""),\n \t\t test$$1,\n \t\t assertLi,\n \t\t assertList;\n\n \t\t// Update remaining tests to aborted\n \t\tif (abortButton && abortButton.disabled) {\n \t\t\thtml = "Tests aborted after " + details.runtime + " milliseconds.";\n\n \t\t\tfor (var i = 0; i < tests.children.length; i++) {\n \t\t\t\ttest$$1 = tests.children[i];\n \t\t\t\tif (test$$1.className === "" || test$$1.className === "running") {\n \t\t\t\t\ttest$$1.className = "aborted";\n \t\t\t\t\tassertList = test$$1.getElementsByTagName("ol")[0];\n \t\t\t\t\tassertLi = document.createElement("li");\n \t\t\t\t\tassertLi.className = "fail";\n \t\t\t\t\tassertLi.innerHTML = "Test aborted.";\n \t\t\t\t\tassertList.appendChild(assertLi);\n \t\t\t\t}\n \t\t\t}\n \t\t}\n\n \t\tif (banner && (!abortButton || abortButton.disabled === false)) {\n \t\t\tbanner.className = stats.failedTests ? "qunit-fail" : "qunit-pass";\n \t\t}\n\n \t\tif (abortButton) {\n \t\t\tabortButton.parentNode.removeChild(abortButton);\n \t\t}\n\n \t\tif (tests) {\n \t\t\tid("qunit-testresult-display").innerHTML = html;\n \t\t}\n\n \t\tif (config.altertitle && document.title) {\n\n \t\t\t// Show \u2716 for good, \u2714 for bad suite result in title\n \t\t\t// use escape sequences in case file gets loaded with non-utf-8\n \t\t\t// charset\n \t\t\tdocument.title = [stats.failedTests ? "\\u2716" : "\\u2714", document.title.replace(/^[\\u2714\\u2716] /i, "")].join(" ");\n \t\t}\n\n \t\t// Scroll back to top to show results\n \t\tif (config.scrolltop && window$1.scrollTo) {\n \t\t\twindow$1.scrollTo(0, 0);\n \t\t}\n \t});\n\n \tfunction getNameHtml(name, module) {\n \t\tvar nameHtml = "";\n\n \t\tif (module) {\n \t\t\tnameHtml = "" + escapeText(module) + ": ";\n \t\t}\n\n \t\tnameHtml += "" + escapeText(name) + "";\n\n \t\treturn nameHtml;\n \t}\n\n \tfunction getProgressHtml(runtime, stats, total) {\n \t\tvar completed = stats.passedTests + stats.skippedTests + stats.todoTests + stats.failedTests;\n\n \t\treturn ["
      ", completed, " / ", total, " tests completed in ", runtime, " milliseconds, with ", stats.failedTests, " failed, ", stats.skippedTests, " skipped, and ", stats.todoTests, " todo."].join("");\n \t}\n\n \tQUnit.testStart(function (details) {\n \t\tvar running, bad;\n\n \t\tappendTest(details.name, details.testId, details.module);\n\n \t\trunning = id("qunit-testresult-display");\n\n \t\tif (running) {\n \t\t\taddClass(running, "running");\n\n \t\t\tbad = QUnit.config.reorder && details.previousFailure;\n\n \t\t\trunning.innerHTML = [bad ? "Rerunning previously failed test:
      " : "Running:
      ", getNameHtml(details.name, details.module), getProgressHtml(now() - config.started, stats, Test.count)].join("");\n \t\t}\n \t});\n\n \tfunction stripHtml(string) {\n\n \t\t// Strip tags, html entity and whitespaces\n \t\treturn string.replace(/<\\/?[^>]+(>|$)/g, "").replace(/"/g, "").replace(/\\s+/g, "");\n \t}\n\n \tQUnit.log(function (details) {\n \t\tvar assertList,\n \t\t assertLi,\n \t\t message,\n \t\t expected,\n \t\t actual,\n \t\t diff$$1,\n \t\t showDiff = false,\n \t\t testItem = id("qunit-test-output-" + details.testId);\n\n \t\tif (!testItem) {\n \t\t\treturn;\n \t\t}\n\n \t\tmessage = escapeText(details.message) || (details.result ? "okay" : "failed");\n \t\tmessage = "" + message + "";\n \t\tmessage += "@ " + details.runtime + " ms";\n\n \t\t// The pushFailure doesn\'t provide details.expected\n \t\t// when it calls, it\'s implicit to also not show expected and diff stuff\n \t\t// Also, we need to check details.expected existence, as it can exist and be undefined\n \t\tif (!details.result && hasOwn$$1.call(details, "expected")) {\n \t\t\tif (details.negative) {\n \t\t\t\texpected = "NOT " + QUnit.dump.parse(details.expected);\n \t\t\t} else {\n \t\t\t\texpected = QUnit.dump.parse(details.expected);\n \t\t\t}\n\n \t\t\tactual = QUnit.dump.parse(details.actual);\n \t\t\tmessage += "";\n\n \t\t\tif (actual !== expected) {\n\n \t\t\t\tmessage += "";\n\n \t\t\t\tif (typeof details.actual === "number" && typeof details.expected === "number") {\n \t\t\t\t\tif (!isNaN(details.actual) && !isNaN(details.expected)) {\n \t\t\t\t\t\tshowDiff = true;\n \t\t\t\t\t\tdiff$$1 = details.actual - details.expected;\n \t\t\t\t\t\tdiff$$1 = (diff$$1 > 0 ? "+" : "") + diff$$1;\n \t\t\t\t\t}\n \t\t\t\t} else if (typeof details.actual !== "boolean" && typeof details.expected !== "boolean") {\n \t\t\t\t\tdiff$$1 = QUnit.diff(expected, actual);\n\n \t\t\t\t\t// don\'t show diff if there is zero overlap\n \t\t\t\t\tshowDiff = stripHtml(diff$$1).length !== stripHtml(expected).length + stripHtml(actual).length;\n \t\t\t\t}\n\n \t\t\t\tif (showDiff) {\n \t\t\t\t\tmessage += "";\n \t\t\t\t}\n \t\t\t} else if (expected.indexOf("[object Array]") !== -1 || expected.indexOf("[object Object]") !== -1) {\n \t\t\t\tmessage += "";\n \t\t\t} else {\n \t\t\t\tmessage += "";\n \t\t\t}\n\n \t\t\tif (details.source) {\n \t\t\t\tmessage += "";\n \t\t\t}\n\n \t\t\tmessage += "
      Expected:
      " + escapeText(expected) + "
      Result:
      " + escapeText(actual) + "
      Diff:
      " + diff$$1 + "
      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) + "
      ";\n\n \t\t\t// This occurs when pushFailure is set and we have an extracted stack trace\n \t\t} else if (!details.result && details.source) {\n \t\t\tmessage += "" + "" + "
      Source:
      " + escapeText(details.source) + "
      ";\n \t\t}\n\n \t\tassertList = testItem.getElementsByTagName("ol")[0];\n\n \t\tassertLi = document.createElement("li");\n \t\tassertLi.className = details.result ? "pass" : "fail";\n \t\tassertLi.innerHTML = message;\n \t\tassertList.appendChild(assertLi);\n \t});\n\n \tQUnit.testDone(function (details) {\n \t\tvar testTitle,\n \t\t time,\n \t\t testItem,\n \t\t assertList,\n \t\t status,\n \t\t good,\n \t\t bad,\n \t\t testCounts,\n \t\t skipped,\n \t\t sourceName,\n \t\t tests = id("qunit-tests");\n\n \t\tif (!tests) {\n \t\t\treturn;\n \t\t}\n\n \t\ttestItem = id("qunit-test-output-" + details.testId);\n\n \t\tremoveClass(testItem, "running");\n\n \t\tif (details.failed > 0) {\n \t\t\tstatus = "failed";\n \t\t} else if (details.todo) {\n \t\t\tstatus = "todo";\n \t\t} else {\n \t\t\tstatus = details.skipped ? "skipped" : "passed";\n \t\t}\n\n \t\tassertList = testItem.getElementsByTagName("ol")[0];\n\n \t\tgood = details.passed;\n \t\tbad = details.failed;\n\n \t\t// This test passed if it has no unexpected failed assertions\n \t\tvar testPassed = details.failed > 0 ? details.todo : !details.todo;\n\n \t\tif (testPassed) {\n\n \t\t\t// Collapse the passing tests\n \t\t\taddClass(assertList, "qunit-collapsed");\n \t\t} else if (config.collapse) {\n \t\t\tif (!collapseNext) {\n\n \t\t\t\t// Skip collapsing the first failing test\n \t\t\t\tcollapseNext = true;\n \t\t\t} else {\n\n \t\t\t\t// Collapse remaining tests\n \t\t\t\taddClass(assertList, "qunit-collapsed");\n \t\t\t}\n \t\t}\n\n \t\t// The testItem.firstChild is the test name\n \t\ttestTitle = testItem.firstChild;\n\n \t\ttestCounts = bad ? "" + bad + ", " + "" + good + ", " : "";\n\n \t\ttestTitle.innerHTML += " (" + testCounts + details.assertions.length + ")";\n\n \t\tif (details.skipped) {\n \t\t\tstats.skippedTests++;\n\n \t\t\ttestItem.className = "skipped";\n \t\t\tskipped = document.createElement("em");\n \t\t\tskipped.className = "qunit-skipped-label";\n \t\t\tskipped.innerHTML = "skipped";\n \t\t\ttestItem.insertBefore(skipped, testTitle);\n \t\t} else {\n \t\t\taddEvent(testTitle, "click", function () {\n \t\t\t\ttoggleClass(assertList, "qunit-collapsed");\n \t\t\t});\n\n \t\t\ttestItem.className = testPassed ? "pass" : "fail";\n\n \t\t\tif (details.todo) {\n \t\t\t\tvar todoLabel = document.createElement("em");\n \t\t\t\ttodoLabel.className = "qunit-todo-label";\n \t\t\t\ttodoLabel.innerHTML = "todo";\n \t\t\t\ttestItem.className += " todo";\n \t\t\t\ttestItem.insertBefore(todoLabel, testTitle);\n \t\t\t}\n\n \t\t\ttime = document.createElement("span");\n \t\t\ttime.className = "runtime";\n \t\t\ttime.innerHTML = details.runtime + " ms";\n \t\t\ttestItem.insertBefore(time, assertList);\n\n \t\t\tif (!testPassed) {\n \t\t\t\tstats.failedTests++;\n \t\t\t} else if (details.todo) {\n \t\t\t\tstats.todoTests++;\n \t\t\t} else {\n \t\t\t\tstats.passedTests++;\n \t\t\t}\n \t\t}\n\n \t\t// Show the source of the test when showing assertions\n \t\tif (details.source) {\n \t\t\tsourceName = document.createElement("p");\n \t\t\tsourceName.innerHTML = "Source: " + escapeText(details.source);\n \t\t\taddClass(sourceName, "qunit-source");\n \t\t\tif (testPassed) {\n \t\t\t\taddClass(sourceName, "qunit-collapsed");\n \t\t\t}\n \t\t\taddEvent(testTitle, "click", function () {\n \t\t\t\ttoggleClass(sourceName, "qunit-collapsed");\n \t\t\t});\n \t\t\ttestItem.appendChild(sourceName);\n \t\t}\n\n \t\tif (config.hidepassed && status === "passed") {\n\n \t\t\t// use removeChild instead of remove because of support\n \t\t\thiddenTests.push(testItem);\n\n \t\t\ttests.removeChild(testItem);\n \t\t}\n \t});\n\n \t// Avoid readyState issue with phantomjs\n \t// Ref: #818\n \tvar notPhantom = function (p) {\n \t\treturn !(p && p.version && p.version.major > 0);\n \t}(window$1.phantom);\n\n \tif (notPhantom && document.readyState === "complete") {\n \t\tQUnit.load();\n \t} else {\n \t\taddEvent(window$1, "load", QUnit.load);\n \t}\n\n \t// Wrap window.onerror. We will call the original window.onerror to see if\n \t// the existing handler fully handles the error; if not, we will call the\n \t// QUnit.onError function.\n \tvar originalWindowOnError = window$1.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$1.onerror = function (message, fileName, lineNumber, columnNumber, errorObj) {\n \t\tvar ret = false;\n \t\tif (originalWindowOnError) {\n \t\t\tfor (var _len = arguments.length, args = Array(_len > 5 ? _len - 5 : 0), _key = 5; _key < _len; _key++) {\n \t\t\t\targs[_key - 5] = arguments[_key];\n \t\t\t}\n\n \t\t\tret = originalWindowOnError.call.apply(originalWindowOnError, [this, message, fileName, lineNumber, columnNumber, errorObj].concat(args));\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\tvar error = {\n \t\t\t\tmessage: message,\n \t\t\t\tfileName: fileName,\n \t\t\t\tlineNumber: lineNumber\n \t\t\t};\n\n \t\t\t// According to\n \t\t\t// https://blog.sentry.io/2016/01/04/client-javascript-reporting-window-onerror,\n \t\t\t// most modern browsers support an errorObj argument; use that to\n \t\t\t// get a full stack trace if it\'s available.\n \t\t\tif (errorObj && errorObj.stack) {\n \t\t\t\terror.stacktrace = extractStacktrace(errorObj, 0);\n \t\t\t}\n\n \t\t\tret = QUnit.onError(error);\n \t\t}\n\n \t\treturn ret;\n \t};\n\n \t// Listen for unhandled rejections, and call QUnit.onUnhandledRejection\n \twindow$1.addEventListener("unhandledrejection", function (event) {\n \t\tQUnit.onUnhandledRejection(event.reason);\n \t});\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 */\n QUnit.diff = function () {\n \tfunction DiffMatchPatch() {}\n\n \t// DIFF FUNCTIONS\n\n \t/**\n * The data structure representing a diff is an array of tuples:\n * [[DIFF_DELETE, \'Hello\'], [DIFF_INSERT, \'Goodbye\'], [DIFF_EQUAL, \' world.\']]\n * which means: delete \'Hello\', add \'Goodbye\' and keep \' world.\'\n */\n \tvar DIFF_DELETE = -1,\n \t DIFF_INSERT = 1,\n \t DIFF_EQUAL = 0;\n\n \t/**\n * Find the differences between two texts. Simplifies the problem by stripping\n * any common prefix or suffix off the texts before diffing.\n * @param {string} text1 Old string to be diffed.\n * @param {string} text2 New string to be diffed.\n * @param {boolean=} optChecklines Optional speedup flag. If present and false,\n * then don\'t run a line-level diff first to identify the changed areas.\n * Defaults to true, which does a faster, slightly less optimal diff.\n * @return {!Array.} Array of diff tuples.\n */\n \tDiffMatchPatch.prototype.DiffMain = function (text1, text2, optChecklines) {\n \t\tvar deadline, checklines, commonlength, commonprefix, 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 [[DIFF_EQUAL, text1]];\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 * Reduce the number of edits by eliminating operationally trivial equalities.\n * @param {!Array.} diffs Array of diff tuples.\n */\n \tDiffMatchPatch.prototype.diffCleanupEfficiency = function (diffs) {\n \t\tvar changes, equalities, equalitiesLength, lastequality, pointer, 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\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 * Five types to be split:\n * ABXYCD\n * AXCD\n * ABXC\n * AXCD\n * ABXC\n */\n \t\t\t\tif (lastequality && (preIns && preDel && postIns && postDel || lastequality.length < 2 && preIns + preDel + postIns + postDel === 3)) {\n\n \t\t\t\t\t// Duplicate record.\n \t\t\t\t\tdiffs.splice(equalities[equalitiesLength - 1], 0, [DIFF_DELETE, lastequality]);\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 * Convert a diff array into a pretty HTML report.\n * @param {!Array.} diffs Array of diff tuples.\n * @param {integer} string to be beautified.\n * @return {string} HTML representation.\n */\n \tDiffMatchPatch.prototype.diffPrettyHtml = function (diffs) {\n \t\tvar op,\n \t\t data,\n \t\t x,\n \t\t html = [];\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\t\tcase DIFF_INSERT:\n \t\t\t\t\thtml[x] = "" + escapeText(data) + "";\n \t\t\t\t\tbreak;\n \t\t\t\tcase DIFF_DELETE:\n \t\t\t\t\thtml[x] = "" + escapeText(data) + "";\n \t\t\t\t\tbreak;\n \t\t\t\tcase DIFF_EQUAL:\n \t\t\t\t\thtml[x] = "" + escapeText(data) + "";\n \t\t\t\t\tbreak;\n \t\t\t}\n \t\t}\n \t\treturn html.join("");\n \t};\n\n \t/**\n * Determine the common prefix of two strings.\n * @param {string} text1 First string.\n * @param {string} text2 Second string.\n * @return {number} The number of characters common to the start of each\n * string.\n */\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) === text2.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 * Determine the common suffix of two strings.\n * @param {string} text1 First string.\n * @param {string} text2 Second string.\n * @return {number} The number of characters common to the end of each string.\n */\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 || !text2 || text1.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) === text2.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 * Find the differences between two texts. Assumes that the texts do not\n * have any common prefix or suffix.\n * @param {string} text1 Old string to be diffed.\n * @param {string} text2 New string to be diffed.\n * @param {boolean} checklines Speedup flag. If false, then don\'t run a\n * line-level diff first to identify the changed areas.\n * If true, then run a faster, slightly less optimal diff.\n * @param {number} deadline Time when the diff should be complete by.\n * @return {!Array.} Array of diff tuples.\n * @private\n */\n \tDiffMatchPatch.prototype.diffCompute = function (text1, text2, checklines, deadline) {\n \t\tvar diffs, longtext, shorttext, i, hm, text1A, text2A, text1B, text2B, midCommon, diffsA, diffsB;\n\n \t\tif (!text1) {\n\n \t\t\t// Just add some text (speedup).\n \t\t\treturn [[DIFF_INSERT, text2]];\n \t\t}\n\n \t\tif (!text2) {\n\n \t\t\t// Just delete some text (speedup).\n \t\t\treturn [[DIFF_DELETE, text1]];\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 = [[DIFF_INSERT, longtext.substring(0, i)], [DIFF_EQUAL, shorttext], [DIFF_INSERT, longtext.substring(i + shorttext.length)]];\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 [[DIFF_DELETE, text1], [DIFF_INSERT, text2]];\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([[DIFF_EQUAL, midCommon]], 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 * Do the two texts share a substring which is at least half the length of the\n * longer text?\n * This speedup can produce non-minimal diffs.\n * @param {string} text1 First string.\n * @param {string} text2 Second string.\n * @return {Array.} Five element Array, containing the prefix of\n * text1, the suffix of text1, the prefix of text2, the suffix of\n * text2 and the common middle. Or null if there was no match.\n * @private\n */\n \tDiffMatchPatch.prototype.diffHalfMatch = function (text1, text2) {\n \t\tvar longtext, shorttext, dmp, text1A, text2B, text2A, text1B, midCommon, hm1, 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 * Does a substring of shorttext exist within longtext such that the substring\n * is at least half the length of longtext?\n * Closure, but does not reference any external variables.\n * @param {string} longtext Longer string.\n * @param {string} shorttext Shorter string.\n * @param {number} i Start index of quarter length substring within longtext.\n * @return {Array.} Five element Array, containing the prefix of\n * longtext, the suffix of longtext, the prefix of shorttext, the suffix\n * of shorttext and the common middle. Or null if there was no match.\n * @private\n */\n \t\tfunction diffHalfMatchI(longtext, shorttext, i) {\n \t\t\tvar seed, j, bestCommon, prefixLength, suffixLength, bestLongtextA, 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), shorttext.substring(j));\n \t\t\t\tsuffixLength = dmp.diffCommonSuffix(longtext.substring(0, i), shorttext.substring(0, j));\n \t\t\t\tif (bestCommon.length < suffixLength + prefixLength) {\n \t\t\t\t\tbestCommon = shorttext.substring(j - suffixLength, j) + shorttext.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, bestShorttextA, bestShorttextB, bestCommon];\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, Math.ceil(longtext.length / 4));\n\n \t\t// Check again based on the third quarter.\n \t\thm2 = diffHalfMatchI(longtext, shorttext, Math.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\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 * Do a quick line-level diff on both strings, then rediff the parts for\n * greater accuracy.\n * This speedup can produce non-minimal diffs.\n * @param {string} text1 Old string to be diffed.\n * @param {string} text2 New string to be diffed.\n * @param {number} deadline Time when the diff should be complete by.\n * @return {!Array.} Array of diff tuples.\n * @private\n */\n \tDiffMatchPatch.prototype.diffLineMode = function (text1, text2, deadline) {\n \t\tvar a, diffs, linearray, pointer, countInsert, countDelete, 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\t\tcase DIFF_INSERT:\n \t\t\t\t\tcountInsert++;\n \t\t\t\t\ttextInsert += diffs[pointer][1];\n \t\t\t\t\tbreak;\n \t\t\t\tcase DIFF_DELETE:\n \t\t\t\t\tcountDelete++;\n \t\t\t\t\ttextDelete += diffs[pointer][1];\n \t\t\t\t\tbreak;\n \t\t\t\tcase DIFF_EQUAL:\n\n \t\t\t\t\t// Upon reaching an equality, check for prior redundancies.\n \t\t\t\t\tif (countDelete >= 1 && countInsert >= 1) {\n\n \t\t\t\t\t\t// Delete the offending records and add the merged ones.\n \t\t\t\t\t\tdiffs.splice(pointer - countDelete - countInsert, countDelete + countInsert);\n \t\t\t\t\t\tpointer = pointer - countDelete - countInsert;\n \t\t\t\t\t\ta = this.DiffMain(textDelete, textInsert, false, deadline);\n \t\t\t\t\t\tfor (j = a.length - 1; j >= 0; j--) {\n \t\t\t\t\t\t\tdiffs.splice(pointer, 0, a[j]);\n \t\t\t\t\t\t}\n \t\t\t\t\t\tpointer = pointer + a.length;\n \t\t\t\t\t}\n \t\t\t\t\tcountInsert = 0;\n \t\t\t\t\tcountDelete = 0;\n \t\t\t\t\ttextDelete = "";\n \t\t\t\t\ttextInsert = "";\n \t\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 * Find the \'middle snake\' of a diff, split the problem in two\n * and return the recursively constructed diff.\n * See Myers 1986 paper: An O(ND) Difference Algorithm and Its Variations.\n * @param {string} text1 Old string to be diffed.\n * @param {string} text2 New string to be diffed.\n * @param {number} deadline Time at which to bail if not yet complete.\n * @return {!Array.} Array of diff tuples.\n * @private\n */\n \tDiffMatchPatch.prototype.diffBisect = function (text1, text2, deadline) {\n \t\tvar text1Length, text2Length, maxD, vOffset, vLength, v1, v2, x, delta, front, k1start, k1end, k2start, k2end, 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 && text1.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 && text1.charAt(text1Length - x2 - 1) === text2.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 [[DIFF_DELETE, text1], [DIFF_INSERT, text2]];\n \t};\n\n \t/**\n * Given the location of the \'middle snake\', split the diff in two parts\n * and recurse.\n * @param {string} text1 Old string to be diffed.\n * @param {string} text2 New string to be diffed.\n * @param {number} x Index of split point in text1.\n * @param {number} y Index of split point in text2.\n * @param {number} deadline Time at which to bail if not yet complete.\n * @return {!Array.} Array of diff tuples.\n * @private\n */\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 * Reduce the number of edits by eliminating semantically trivial equalities.\n * @param {!Array.} diffs Array of diff tuples.\n */\n \tDiffMatchPatch.prototype.diffCleanupSemantic = function (diffs) {\n \t\tvar changes, equalities, equalitiesLength, lastequality, pointer, lengthInsertions2, lengthDeletions2, lengthInsertions1, lengthDeletions1, 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) {\n \t\t\t\t// 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 {\n \t\t\t\t// 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 <= Math.max(lengthInsertions1, lengthDeletions1) && lastequality.length <= Math.max(lengthInsertions2, lengthDeletions2)) {\n\n \t\t\t\t\t// Duplicate record.\n \t\t\t\t\tdiffs.splice(equalities[equalitiesLength - 1], 0, [DIFF_DELETE, lastequality]);\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 && diffs[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 || overlapLength1 >= 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(pointer, 0, [DIFF_EQUAL, insertion.substring(0, overlapLength1)]);\n \t\t\t\t\t\tdiffs[pointer - 1][1] = deletion.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 || overlapLength2 >= 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(pointer, 0, [DIFF_EQUAL, deletion.substring(0, overlapLength2)]);\n\n \t\t\t\t\t\tdiffs[pointer - 1][0] = DIFF_INSERT;\n \t\t\t\t\t\tdiffs[pointer - 1][1] = insertion.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] = deletion.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 * Determine if the suffix of one string is the prefix of another.\n * @param {string} text1 First string.\n * @param {string} text2 Second string.\n * @return {number} The number of characters common to the end of the first\n * string and the start of the second string.\n * @private\n */\n \tDiffMatchPatch.prototype.diffCommonOverlap = function (text1, text2) {\n \t\tvar text1Length, text2Length, textLength, best, 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) === text2.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 * Split two texts into an array of strings. Reduce the texts to a string of\n * hashes where each Unicode character represents one line.\n * @param {string} text1 First string.\n * @param {string} text2 Second string.\n * @return {{chars1: string, chars2: string, lineArray: !Array.}}\n * An object containing the encoded text1, the encoded text2 and\n * the array of unique strings.\n * The zeroth element of the array of unique strings is intentionally blank.\n * @private\n */\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 * Split a text into an array of strings. Reduce the texts to a string of\n * hashes where each Unicode character represents one line.\n * Modifies linearray and linehash through being a closure.\n * @param {string} text String to encode.\n * @return {string} Encoded string.\n * @private\n */\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\tvar lineHashExists = lineHash.hasOwnProperty ? lineHash.hasOwnProperty(line) : lineHash[line] !== undefined;\n\n \t\t\t\tif (lineHashExists) {\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 * Rehydrate the text in a diff from a string of line hashes to real lines of\n * text.\n * @param {!Array.} diffs Array of diff tuples.\n * @param {!Array.} lineArray Array of unique strings.\n * @private\n */\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 * Reorder and merge like edit sections. Merge equalities.\n * Any edit section can move as long as it doesn\'t cross an equality.\n * @param {!Array.} diffs Array of diff tuples.\n */\n \tDiffMatchPatch.prototype.diffCleanupMerge = function (diffs) {\n \t\tvar pointer, countDelete, countInsert, textInsert, textDelete, commonlength, 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\n \t\twhile (pointer < diffs.length) {\n \t\t\tswitch (diffs[pointer][0]) {\n \t\t\t\tcase DIFF_INSERT:\n \t\t\t\t\tcountInsert++;\n \t\t\t\t\ttextInsert += diffs[pointer][1];\n \t\t\t\t\tpointer++;\n \t\t\t\t\tbreak;\n \t\t\t\tcase DIFF_DELETE:\n \t\t\t\t\tcountDelete++;\n \t\t\t\t\ttextDelete += diffs[pointer][1];\n \t\t\t\t\tpointer++;\n \t\t\t\t\tbreak;\n \t\t\t\tcase DIFF_EQUAL:\n\n \t\t\t\t\t// Upon reaching an equality, check for prior redundancies.\n \t\t\t\t\tif (countDelete + countInsert > 1) {\n \t\t\t\t\t\tif (countDelete !== 0 && countInsert !== 0) {\n\n \t\t\t\t\t\t\t// Factor out any common prefixes.\n \t\t\t\t\t\t\tcommonlength = this.diffCommonPrefix(textInsert, textDelete);\n \t\t\t\t\t\t\tif (commonlength !== 0) {\n \t\t\t\t\t\t\t\tif (pointer - countDelete - countInsert > 0 && diffs[pointer - countDelete - countInsert - 1][0] === DIFF_EQUAL) {\n \t\t\t\t\t\t\t\t\tdiffs[pointer - countDelete - countInsert - 1][1] += textInsert.substring(0, commonlength);\n \t\t\t\t\t\t\t\t} else {\n \t\t\t\t\t\t\t\t\tdiffs.splice(0, 0, [DIFF_EQUAL, textInsert.substring(0, commonlength)]);\n \t\t\t\t\t\t\t\t\tpointer++;\n \t\t\t\t\t\t\t\t}\n \t\t\t\t\t\t\t\ttextInsert = textInsert.substring(commonlength);\n \t\t\t\t\t\t\t\ttextDelete = textDelete.substring(commonlength);\n \t\t\t\t\t\t\t}\n\n \t\t\t\t\t\t\t// Factor out any common suffixies.\n \t\t\t\t\t\t\tcommonlength = this.diffCommonSuffix(textInsert, textDelete);\n \t\t\t\t\t\t\tif (commonlength !== 0) {\n \t\t\t\t\t\t\t\tdiffs[pointer][1] = textInsert.substring(textInsert.length - commonlength) + diffs[pointer][1];\n \t\t\t\t\t\t\t\ttextInsert = textInsert.substring(0, textInsert.length - commonlength);\n \t\t\t\t\t\t\t\ttextDelete = textDelete.substring(0, textDelete.length - commonlength);\n \t\t\t\t\t\t\t}\n \t\t\t\t\t\t}\n\n \t\t\t\t\t\t// Delete the offending records and add the merged ones.\n \t\t\t\t\t\tif (countDelete === 0) {\n \t\t\t\t\t\t\tdiffs.splice(pointer - countInsert, countDelete + countInsert, [DIFF_INSERT, textInsert]);\n \t\t\t\t\t\t} else if (countInsert === 0) {\n \t\t\t\t\t\t\tdiffs.splice(pointer - countDelete, countDelete + countInsert, [DIFF_DELETE, textDelete]);\n \t\t\t\t\t\t} else {\n \t\t\t\t\t\t\tdiffs.splice(pointer - countDelete - countInsert, countDelete + countInsert, [DIFF_DELETE, textDelete], [DIFF_INSERT, textInsert]);\n \t\t\t\t\t\t}\n \t\t\t\t\t\tpointer = pointer - countDelete - countInsert + (countDelete ? 1 : 0) + (countInsert ? 1 : 0) + 1;\n \t\t\t\t\t} else if (pointer !== 0 && diffs[pointer - 1][0] === DIFF_EQUAL) {\n\n \t\t\t\t\t\t// Merge this equality with the previous one.\n \t\t\t\t\t\tdiffs[pointer - 1][1] += diffs[pointer][1];\n \t\t\t\t\t\tdiffs.splice(pointer, 1);\n \t\t\t\t\t} else {\n \t\t\t\t\t\tpointer++;\n \t\t\t\t\t}\n \t\t\t\t\tcountInsert = 0;\n \t\t\t\t\tcountDelete = 0;\n \t\t\t\t\ttextDelete = "";\n \t\t\t\t\ttextInsert = "";\n \t\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 && diffs[pointer + 1][0] === DIFF_EQUAL) {\n\n \t\t\t\tdiffPointer = diffs[pointer][1];\n \t\t\t\tposition = diffPointer.substring(diffPointer.length - diffs[pointer - 1][1].length);\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] + diffs[pointer][1].substring(0, diffs[pointer][1].length - diffs[pointer - 1][1].length);\n \t\t\t\t\tdiffs[pointer + 1][1] = diffs[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) === diffs[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] = diffs[pointer][1].substring(diffs[pointer + 1][1].length) + 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}\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}((function() { return this; }())));\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@2.0.0#steal-qunit*/ +'format amd'; +define('steal-qunit@2.0.0#steal-qunit', [ + '@loader', + 'qunit/qunit/qunit', + 'qunit/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.autostart = false; + steal.done().then(function () { + if (window.Testee && window.Testee.init) { + Testee.init(); + } + var qunitVersion = Number(QUnit.version.split('.')[0]); + if (qunitVersion < 2) { + 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.5#can-symbol*/ +define('can-symbol@1.6.5#can-symbol', [ + 'require', + 'exports', + 'module', + 'can-namespace' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + var supportsNativeSymbols = function () { + var symbolExists = typeof Symbol !== 'undefined' && typeof Symbol.for === 'function'; + if (!symbolExists) { + return false; + } + var symbol = Symbol('a symbol for testing symbols'); + return typeof symbol === 'symbol'; + }(); + var CanSymbol; + if (supportsNativeSymbols) { + 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.18.0#reflections/helpers*/ +define('can-reflect@1.18.0#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.18.0#reflections/type/type*/ +define('can-reflect@1.18.0#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 supportsNativeSymbols = function () { + var symbolExists = typeof Symbol !== 'undefined' && typeof Symbol.for === 'function'; + if (!symbolExists) { + return false; + } + var symbol = Symbol('a symbol for testing symbols'); + return typeof symbol === 'symbol'; + }(); + var isSymbolLike; + if (supportsNativeSymbols) { + 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.18.0#reflections/call/call*/ +define('can-reflect@1.18.0#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.18.0#reflections/get-set/get-set*/ +define('can-reflect@1.18.0#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.18.0#reflections/observe/observe*/ +define('can-reflect@1.18.0#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.18.0#reflections/shape/shape*/ +define('can-reflect@1.18.0#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) && !typeReflections.isObservableLike(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.18.0#reflections/shape/schema/schema*/ +define('can-reflect@1.18.0#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) || obj instanceof Date) { + 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.18.0#reflections/get-name/get-name*/ +define('can-reflect@1.18.0#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.18.0#types/map*/ +define('can-reflect@1.18.0#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.18.0#types/set*/ +define('can-reflect@1.18.0#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.18.0#can-reflect*/ +define('can-reflect@1.18.0#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.2#can-globals-proto*/ +define('can-globals@1.2.2#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.2#can-globals-instance*/ +define('can-globals@1.2.2#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.2#global/global*/ +define('can-globals@1.2.2#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.2#mutation-observer/mutation-observer*/ +define('can-globals@1.2.2#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.2#document/document*/ +define('can-globals@1.2.2#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.2#location/location*/ +define('can-globals@1.2.2#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.2#is-node/is-node*/ +define('can-globals@1.2.2#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.2#is-browser-window/is-browser-window*/ +define('can-globals@1.2.2#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.2#custom-elements/custom-elements*/ +define('can-globals@1.2.2#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.2#can-globals*/ +define('can-globals@1.2.2#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-child-nodes@1.2.1#can-child-nodes*/ +define('can-child-nodes@1.2.1#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-simple-dom@1.7.0#lib/document/compare-document-position*/ +define('can-simple-dom@1.7.0#lib/document/compare-document-position', [ + 'require', + 'exports', + 'module', + 'can-child-nodes' +], function (require, exports, module) { + var getChildNodes = require('can-child-nodes'); + module.exports = function (Node) { + Node.DOCUMENT_POSITION_DISCONNECTED = 1; + Node.DOCUMENT_POSITION_PRECEDING = 2; + Node.DOCUMENT_POSITION_FOLLOWING = 4; + Node.DOCUMENT_POSITION_CONTAINS = 8; + Node.DOCUMENT_POSITION_CONTAINED_BY = 16; + Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 32; + Node.prototype.compareDocumentPosition = function (other) { + function getFirstNodeByOrder(nodes, nodeOne, nodeTwo) { + return nodes.reduce(function (result, node) { + if (result !== false) { + return result; + } else if (node === nodeOne) { + return nodeOne; + } else if (node === nodeTwo) { + return nodeTwo; + } else if (node.childNodes) { + return getFirstNodeByOrder(getChildNodes(node), nodeOne, nodeTwo); + } else { + return false; + } + }, false); + } + function isAncestor(source, target) { + while (target.parentNode) { + target = target.parentNode; + if (target === source) { + return true; + } + } + return false; + } + function eitherContains(left, right) { + return isAncestor(left, right) ? Node.DOCUMENT_POSITION_CONTAINED_BY + Node.DOCUMENT_POSITION_FOLLOWING : isAncestor(right, left) ? Node.DOCUMENT_POSITION_CONTAINS + Node.DOCUMENT_POSITION_PRECEDING : false; + } + function getRootNode(node) { + while (node.parentNode) { + node = node.parentNode; + } + return node; + } + if (this === other) { + return 0; + } + var referenceRoot = getRootNode(this); + var otherRoot = getRootNode(other); + if (referenceRoot !== otherRoot) { + return Node.DOCUMENT_POSITION_DISCONNECTED; + } + var result = eitherContains(this, other); + if (result) { + return result; + } + var first = getFirstNodeByOrder([referenceRoot], this, other); + return first === this ? Node.DOCUMENT_POSITION_FOLLOWING : first === other ? Node.DOCUMENT_POSITION_PRECEDING : Node.DOCUMENT_POSITION_DISCONNECTED; + }; + }; +}); +/*can-simple-dom@1.7.0#lib/document/node*/ +define('can-simple-dom@1.7.0#lib/document/node', [ + 'require', + 'exports', + 'module', + './compare-document-position' +], function (require, exports, module) { + var makeCompareDocumentPosition = require('./compare-document-position'); + 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 () { + }; + makeCompareDocumentPosition(Node); + 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.7.0#lib/document/style*/ +define('can-simple-dom@1.7.0#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.7.0#lib/document/element*/ +define('can-simple-dom@1.7.0#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.setAttributeNS = function (namespaceURI, name, value) { + this._setAttribute(name, value); + var i = this.attributes.length; + do { + i--; + var attrNode = this.attributes[i]; + if (attrNode.name === name) { + attrNode.namespaceURI = namespaceURI; + break; + } + } while (i > 0); + }; + 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.7.0#lib/document/text*/ +define('can-simple-dom@1.7.0#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.7.0#lib/document/comment*/ +define('can-simple-dom@1.7.0#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.7.0#lib/document/document-fragment*/ +define('can-simple-dom@1.7.0#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.7.0#lib/extend*/ +define('can-simple-dom@1.7.0#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.7.0#lib/document/anchor-element*/ +define('can-simple-dom@1.7.0#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); + Object.defineProperty(this, '_href', { + enumerable: false, + configurable: true, + writable: true, + value: '' + }); + 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)); + } + }; + Object.defineProperty(AnchorElement.prototype, 'href', { + get: function () { + return this._href; + }, + set: function (val) { + if (val !== this._href) { + this._href = val; + this.setAttribute('href', val); + } + } + }); + module.exports = AnchorElement; +}); +/*can-simple-dom@1.7.0#lib/document/utils*/ +define('can-simple-dom@1.7.0#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.7.0#lib/document/input-element*/ +define('can-simple-dom@1.7.0#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.7.0#lib/document/option-element*/ +define('can-simple-dom@1.7.0#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.7.0#lib/document/select-element*/ +define('can-simple-dom@1.7.0#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.7.0#lib/document*/ +define('can-simple-dom@1.7.0#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.7.0#lib/event*/ +define('can-simple-dom@1.7.0#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.7.0#lib/html-parser*/ +define('can-simple-dom@1.7.0#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.7.0#lib/html-serializer*/ +define('can-simple-dom@1.7.0#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.7.0#lib/void-map*/ +define('can-simple-dom@1.7.0#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.7.0#lib/dom*/ +define('can-simple-dom@1.7.0#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.7.0#can-simple-dom*/ +define('can-simple-dom@1.7.0#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.2#can-log*/ +define('can-log@1.0.2#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.2#dev/dev*/ +define('can-log@1.0.2#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.4#can-attribute-encoder*/ +define('can-attribute-encoder@1.1.4#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,controlsList'); + 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]|[0-9]|^)([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.3#can-view-parser*/ +define('can-view-parser@4.1.3#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.2#make-parser/make-parser*/ +define('can-vdom@4.4.2#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.2#make-document/make-document*/ +define('can-vdom@4.4.2#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.11#-util*/ +define('can-dom-mutate@1.3.11#-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.11#can-dom-mutate*/ +define('can-dom-mutate@1.3.11#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 WeakMap(); + 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.11#node/node*/ +define('can-dom-mutate@1.3.11#node/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; + }, + setAttributeNS: function (namespace, name, value) { + var oldAttributeValue = this.getAttribute(name); + var result = this.setAttributeNS(namespace, 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', + 'setAttributeNS', + '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-dom-mutate@1.3.11#node*/ +define('can-dom-mutate@1.3.11#node', [ + 'require', + 'exports', + 'module', + 'can-namespace', + './node/node' +], function (require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + var node = require('./node/node'); + module.exports = namespace.node = node; +}); +/*can-component@4.6.2#test/helpers*/ +define('can-component@4.6.2#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, done) { + var nextTask = function () { + var next = tasks.shift(); + next(); + if (tasks.length) { + setTimeout(nextTask, 100); + } else { + done(); + } + }; + setTimeout(nextTask, 100); + }, + makeTest: function (name, doc, mutObs, test, qUnitTest) { + var DOC = DOCUMENT(); + QUnit.module(name, { + beforeEach: function (assert) { + 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'); + } + }, + afterEach: function (assert) { + doc.body.removeChild(this.fixture); + var done = assert.async(); + setTimeout(function () { + done(); + 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.1.0#can-string*/ +define('can-string@1.1.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(); + }); + }, + pascalize: function (str) { + return string.capitalize(string.camelize(str)); + }, + 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.6#can-construct*/ +define('can-construct@3.5.6#can-construct', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-log/dev/dev', + 'can-namespace', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var dev = require('can-log/dev/dev'); + var namespace = require('can-namespace'); + var canSymbol = require('can-symbol'); + var inSetupSymbol = canSymbol.for('can.initializing'); + 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 + }); + Object.defineProperty(inst, inSetupSymbol, { + 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; + inst[inSetupSymbol] = 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 = base.defaults ? canReflect.serialize(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.3.1#queue-state*/ +define('can-queues@1.3.1#queue-state', function (require, exports, module) { + 'use strict'; + module.exports = { lastTask: null }; +}); +/*can-assign@1.3.3#can-assign*/ +define('can-assign@1.3.3#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.3.1#queue*/ +define('can-queues@1.3.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.3.1#priority-queue*/ +define('can-queues@1.3.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.3.1#completion-queue*/ +define('can-queues@1.3.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.3.1#sorted-index-by*/ +define('can-queues@1.3.1#sorted-index-by', function (require, exports, module) { + module.exports = function (compare, array, value) { + if (!array || !array.length) { + return undefined; + } + if (compare(value, array[0]) === -1) { + return 0; + } else if (compare(value, array[array.length - 1]) === 1) { + return array.length; + } + var low = 0, high = array.length; + while (low < high) { + var mid = low + high >>> 1, item = array[mid], computed = compare(value, item); + if (computed === -1) { + high = mid; + } else { + low = mid + 1; + } + } + return high; + }; +}); +/*can-queues@1.3.1#element-sort*/ +define('can-queues@1.3.1#element-sort', function (require, exports, module) { + var hasDuplicate, sortInput, sortStable = true, indexOf = Array.prototype.indexOf; + function sortOrder(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) { + if (a === document || a.ownerDocument === document && document.documentElement.contains(a)) { + return -1; + } + if (b === document || b.ownerDocument === document && document.documentElement.contains(b)) { + return 1; + } + return sortInput ? indexOf.call(sortInput, a) - indexOf.call(sortInput, b) : 0; + } + return compare & 4 ? -1 : 1; + } + function uniqueSort(results) { + var elem, duplicates = [], j = 0, i = 0; + hasDuplicate = false; + sortInput = !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; + } + module.exports = { + uniqueSort: uniqueSort, + sortOrder: sortOrder + }; +}); +/*can-queues@1.3.1#dom-order-queue*/ +define('can-queues@1.3.1#dom-order-queue', [ + 'require', + 'exports', + 'module', + './queue', + './sorted-index-by', + './element-sort', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var Queue = require('./queue'); + var sortedIndexBy = require('./sorted-index-by'); + var elementSort = require('./element-sort'); + var canSymbol = require('can-symbol'); + var canElementSymbol = canSymbol.for('can.element'); + function sortTasks(taskA, taskB) { + return elementSort.sortOrder(taskA.meta.element, taskB.meta.element); + } + var DomOrderQueue = function () { + Queue.apply(this, arguments); + this.taskMap = new Map(); + this.unsortable = []; + this.isFlushing = false; + }; + DomOrderQueue.prototype = Object.create(Queue.prototype); + DomOrderQueue.prototype.constructor = DomOrderQueue; + DomOrderQueue.prototype.enqueue = function (fn, context, args, meta) { + var task; + if (!this.taskMap.has(fn)) { + if (!meta) { + meta = {}; + } + if (!meta.element) { + meta.element = fn[canElementSymbol]; + } + task = { + fn: fn, + context: context, + args: args, + meta: meta + }; + this.taskMap.set(fn, task); + var index = sortedIndexBy(sortTasks, this.tasks, task); + this.tasks.splice(index, 0, task); + if (this.tasks.length === 1) { + this.callbacks.onFirstTask(this); + } + } else { + task = this.taskMap.get(fn); + task.context = context; + task.args = args; + if (!meta) { + meta = {}; + } + if (!meta.element) { + meta.element = fn[canElementSymbol]; + } + task.meta = meta; + } + }; + DomOrderQueue.prototype.flush = function () { + if (this.isFlushing) { + return; + } + this.isFlushing = true; + while (this.tasks.length) { + var task = this.tasks.shift(); + this.taskMap['delete'](task.fn); + task.fn.apply(task.context, task.args); + } + this.isFlushing = false; + this.callbacks.onComplete(this); + }; + DomOrderQueue.prototype.isEnqueued = function (fn) { + return this.taskMap.has(fn); + }; + DomOrderQueue.prototype.flushQueuedTask = function (fn) { + var task = this.dequeue(fn); + if (task) { + task.fn.apply(task.context, task.args); + } + }; + DomOrderQueue.prototype.dequeue = function (fn) { + var task = this.taskMap.get(fn); + if (task) { + var index = this.tasks.indexOf(task); + if (index >= 0) { + this.tasks.splice(index, 1); + this.taskMap['delete'](task.fn); + return task; + } else { + console.warn('Task', fn, 'has already run'); + } + } + }; + DomOrderQueue.prototype.tasksRemainingCount = function () { + return this.tasks.length; + }; + module.exports = DomOrderQueue; +}); +/*can-queues@1.3.1#can-queues*/ +define('can-queues@1.3.1#can-queues', [ + 'require', + 'exports', + 'module', + 'can-log/dev/dev', + './queue', + './priority-queue', + './queue-state', + './completion-queue', + './dom-order-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 DomOrderQueue = require('./dom-order-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', + 'dom', + 'mutate' + ]; + var NOTIFY_QUEUE, DERIVE_QUEUE, DOM_UI_QUEUE, DOM_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_QUEUE.flush(); + }, + onFirstTask: function () { + addedTask = true; + } + }); + DOM_QUEUE = new DomOrderQueue('DOM ', { + 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, + DomOrderQueue: DomOrderQueue, + notifyQueue: NOTIFY_QUEUE, + deriveQueue: DERIVE_QUEUE, + domQueue: DOM_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); + DOM_QUEUE.log.apply(DOM_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.2#can-key-tree*/ +define('can-key-tree@1.2.2#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.11#helpers/util*/ +define('can-dom-events@1.3.11#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.11#helpers/make-event-registry*/ +define('can-dom-events@1.3.11#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.11#helpers/-make-delegate-event-tree*/ +define('can-dom-events@1.3.11#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) { + var cur = ev.target; + var propagate = true; + var origStopPropagation = ev.stopPropagation; + ev.stopPropagation = function () { + origStopPropagation.apply(this, arguments); + propagate = false; + }; + var origStopImmediatePropagation = ev.stopImmediatePropagation; + ev.stopImmediatePropagation = function () { + origStopImmediatePropagation.apply(this, arguments); + propagate = false; + }; + do { + var el = cur === document ? document.documentElement : cur; + var matches = el.matches || el.msMatchesSelector; + canReflect.each(handlersBySelector, function (handlers, selector) { + if (matches && matches.call(el, selector)) { + handlers.forEach(function (handler) { + handler.call(el, ev); + }); + } + }); + cur = cur.parentNode; + } while (cur && cur !== ev.currentTarget && propagate); + }; + 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.11#can-dom-events*/ +define('can-dom-events@1.3.11#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.7#dependency-record/merge*/ +define('can-event-queue@1.1.7#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.7#map/map*/ +define('can-event-queue@1.1.7#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'), inSetupSymbol = canSymbol.for('can.initializing'); + 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 !== true && this[inSetupSymbol] !== true) { + 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 (this[onEventSymbol]) { + this[onEventSymbol](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 (!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 (this[offEventSymbol]) { + this[offEventSymbol](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 (!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.3.1#can-observation-recorder*/ +define('can-observation-recorder@1.3.1#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'), getValueSymbol = canSymbol.for('can.getValue'); + var ObservationRecorder = { + stack: stack, + start: function (name) { + var deps = { + keyDependencies: new Map(), + valueDependencies: new Set(), + childDependencies: new Set(), + traps: null, + ignore: 0, + name: name + }; + 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); + } + }; + }, + peekValue: function (value) { + if (!value || !value[getValueSymbol]) { + return value; + } + if (stack.length) { + var top = stack[stack.length - 1]; + top.ignore++; + var res = value[getValueSymbol](); + top.ignore--; + return res; + } else { + return value[getValueSymbol](); + } + }, + isRecording: function () { + var len = stack.length; + var last = len && stack[len - 1]; + return last && last.ignore === 0 && last; + }, + makeDependenciesRecord: function (name) { + return { + traps: null, + keyDependencies: new Map(), + valueDependencies: new Set(), + ignore: 0, + name: name + }; + }, + 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.2#can-simple-map*/ +define('can-simple-map@4.3.2#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.4#can-view-nodelist*/ +define('can-view-nodelist@4.3.4#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; + var child; + for (var i = 0; i < elementsToBeRemoved.length; i++) { + child = elementsToBeRemoved[i]; + if (child.parentNode === parent) { + domMutate.removeChild.call(parent, child); + } + } + }, + nodeMap: nodeMap + }; + module.exports = namespace.nodeLists = nodeLists; +}); +/*can-fragment@1.3.1#can-fragment*/ +define('can-fragment@1.3.1#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.4.1#can-view-callbacks*/ +define('can-view-callbacks@4.4.1#can-view-callbacks', [ + 'require', + 'exports', + 'module', + 'can-observation-recorder', + 'can-log/dev/dev', + 'can-globals/global/global', + 'can-globals/document/document', + 'can-dom-mutate', + '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 getDocument = require('can-globals/document/document'); + var domMutate = require('can-dom-mutate'); + var domMutateNode = 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 initializeSymbol = canSymbol.for('can.initialize'); + 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 mutationObserverEnabled = false; + var disableMutationObserver; + var enableMutationObserver = function () { + var docEl = getDocument().documentElement; + if (mutationObserverEnabled) { + if (mutationObserverEnabled === docEl) { + return; + } + disableMutationObserver(); + } + var undoOnInsertionHandler = domMutate.onInsertion(docEl, function (mutation) { + mountElement(mutation.target); + }); + mutationObserverEnabled = true; + disableMutationObserver = function () { + undoOnInsertionHandler(); + mutationObserverEnabled = false; + }; + }; + var renderTagsInDocument = function (tagName) { + var nodes = getDocument().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 validCustomElementName = automaticCustomElementCharacters.test(tagName), tagExists = typeof tags[tagName.toLowerCase()] !== 'undefined', customElementExists; + 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) { + disableMutationObserver(); + } + } 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] || el[initializeSymbol], 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; + domMutateNode.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.6#can-view-target*/ +define('can-view-target@4.1.6#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.callbacks.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.1#can-reflect-promise*/ +define('can-reflect-promise@2.2.1#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.3#can-stache-key*/ +define('can-stache-key@1.4.3#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 isPromiseLike = ObservationRecorder.ignore(function isPromiseLike(value) { + return typeof value === 'object' && value && typeof value.then === 'function'; + }); + 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) || isPromiseLike(value)) { + 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.13.6#template-context*/ +define('can-view-scope@4.13.6#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.1#define-lazy-value*/ +define('can-define-lazy-value@1.1.1#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.7#value/value*/ +define('can-event-queue@1.1.7#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.2.0#recorder-dependency-helpers*/ +define('can-observation@4.2.0#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.2.0#temporarily-bind*/ +define('can-observation@4.2.0#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.2.0#can-observation*/ +define('can-observation@4.2.0#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.deriveQueue = queues.deriveQueue; + 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._name); + 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, + element: this.options.element + } + ]; + this.deriveQueue.enqueue.apply(this.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.makeDependenciesRecord(); + }, + get: function () { + if (this.options.isObservable && ObservationRecorder.isRecording()) { + ObservationRecorder.add(this); + if (this.bound === false) { + Observation.temporarilyBind(this); + } + } + if (this.bound === true) { + if (this.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; + }, + 'can.setElement': function (element) { + this.options.element = element; + this.deriveQueue = queues.domQueue || queues.deriveQueue; + } + }; + canReflect.assignSymbols(Observation.prototype, observationProto); + Observation.updateChildrenAndSelf = function (observation) { + if (observation.update !== undefined && observation.deriveQueue.isEnqueued(observation.update) === true) { + observation.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.1#can-cid*/ +define('can-cid@1.3.1#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.3.0#can-single-reference*/ +define('can-single-reference@1.3.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.13.6#make-compute-like*/ +define('can-view-scope@4.13.6#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.2#src/add-mutated-by*/ +define('can-reflect-dependencies@1.1.2#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.2#src/delete-mutated-by*/ +define('can-reflect-dependencies@1.1.2#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.2#src/is-function*/ +define('can-reflect-dependencies@1.1.2#src/is-function', function (require, exports, module) { + 'use strict'; + module.exports = function isFunction(value) { + return typeof value === 'function'; + }; +}); +/*can-reflect-dependencies@1.1.2#src/get-dependency-data-of*/ +define('can-reflect-dependencies@1.1.2#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.2#can-reflect-dependencies*/ +define('can-reflect-dependencies@1.1.2#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.5.0#log*/ +define('can-simple-observable@2.5.0#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.5.0#can-simple-observable*/ +define('can-simple-observable@2.5.0#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.13.6#scope-key-data*/ +define('can-view-scope@4.13.6#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', + 'can-log/dev/dev' +], 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 dev = require('can-log/dev/dev'); + var dispatchSymbol = canSymbol.for('can.dispatch'); + var setElementSymbol = canSymbol.for('can.setElement'); + 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 getMutated(scopeKeyData) { + var value = ObservationRecorder.peekValue(scopeKeyData._thisArg); + return !canReflect.isPrimitive(value) ? value : scopeKeyData.root; + } + 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 warnOnUndefinedProperty; + 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.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 = ObservationRecorder.peekValue(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 ObservationRecorder.peekValue(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 data.value; + }, + hasDependencies: function () { + if (!this.bound) { + Observation.temporarilyBind(this); + } + 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); + }, + 'can.setElement': function (element) { + this.observation[setElementSymbol](element); + } + }; + 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 + }); + Object.defineProperty(ScopeKeyData.prototype, 'initialValue', { + get: function () { + if (!this.bound) { + Observation.temporarilyBind(this); + } + return ObservationRecorder.peekValue(this); + }, + set: function () { + throw new Error('initialValue should not be set'); + }, + configurable: true + }); + module.exports = ScopeKeyData; +}); +/*can-view-scope@4.13.6#compute_data*/ +define('can-view-scope@4.13.6#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.13.6#let-context*/ +define('can-view-scope@4.13.6#let-context', [ + 'require', + 'exports', + 'module', + 'can-simple-map' +], function (require, exports, module) { + var SimpleMap = require('can-simple-map'); + function objectCreateWithSymbolsAndSpecificProperties(obj, propertiesToKeep) { + var newObj = {}; + if ('getOwnPropertySymbols' in Object) { + Object.getOwnPropertySymbols(obj).forEach(function (key) { + newObj[key] = obj[key]; + }); + } + Object.getOwnPropertyNames(obj).forEach(function (key) { + if (propertiesToKeep.indexOf(key) >= 0 || key.indexOf('@@symbol') === 0) { + newObj[key] = obj[key]; + } + }); + return Object.create(newObj); + } + var LetContext = SimpleMap.extend('LetContext', {}); + LetContext.prototype = objectCreateWithSymbolsAndSpecificProperties(SimpleMap.prototype, [ + 'setup', + 'attr', + 'serialize', + 'get', + 'set', + 'log', + 'dispatch', + 'constructorExtends', + 'newInstance', + '_inherit', + '_defineProperty', + '_overwrite', + 'instance', + 'extend', + 'ReturnValue', + 'setup', + 'init' + ]); + LetContext.prototype.constructor = LetContext; + module.exports = LetContext; +}); +/*can-view-scope@4.13.6#can-view-scope*/ +define('can-view-scope@4.13.6#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', + './let-context' +], 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 LetContext = require('./let-context'); + function canHaveProperties(obj) { + return obj != null; + } + function returnFalse() { + return false; + } + 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`: https://canjs.com/doc/can-stache/keys/scope.html#scope_top or `scope.vm`: https://canjs.com/doc/can-stache/keys/scope.html#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', + 'args' + ]; + 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.5.0#settable/settable*/ +define('can-simple-observable@2.5.0#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.17.21#src/key-observable*/ +define('can-stache@4.17.21#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.17.21#src/utils*/ +define('can-stache@4.17.21#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.17.21#src/html_section*/ +define('can-stache@4.17.21#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.8#lib/core*/ +define('can-view-live@4.2.8#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@1.0.3#can-dom-data*/ +define('can-dom-data@1.0.3#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-diff@1.5.0#list/list*/ +define('can-diff@1.5.0#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.2.7#behaviors*/ +define('can-attribute-observable@1.2.7#behaviors', [ + 'require', + 'exports', + 'module', + 'can-globals/document/document', + 'can-globals/global/global', + 'can-dom-data', + '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'); + 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 xmlnsAttrNamespaceURI = 'http://www.w3.org/2000/xmlns/'; + var xlinkHrefAttrNamespaceURI = 'http://www.w3.org/1999/xlink'; + var attrsNamespacesURI = { + 'xmlns': xmlnsAttrNamespaceURI, + 'xlink:href': xlinkHrefAttrNamespaceURI + }; + 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(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(el, 'attrMO', observer); + } else { + setData.set(el, 'attrMO', true); + setData.set(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(select, 'attrSetChildOptions'); + if (handler) { + return Function.prototype; + } + handler = function () { + setChildOptions(select, select.value); + }; + setData.set(select, 'attrSetChildOptions', handler); + aEL.call(select, 'change', handler); + return function (rEL) { + setData.clean(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(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(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' || nodeName === 'textarea') { + 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(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(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(this, 'stickyValues', attr.get(this, 'values')); + setupMO(this, function () { + var previousValues = setData.get(this, 'stickyValues'); + attr.set(this, 'values', previousValues); + var currentValues = setData.get(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) { + if (attrsNamespacesURI[attrName]) { + domMutateNode.setAttributeNS.call(this, attrsNamespacesURI[attrName], attrName, val); + } else { + 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.8#lib/attr*/ +define('can-view-live@4.2.8#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.8#lib/attrs*/ +define('can-view-live@4.2.8#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.8#lib/html*/ +define('can-view-live@4.2.8#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.8#lib/set-observable*/ +define('can-view-live@4.2.8#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.5.0#patcher/patcher*/ +define('can-diff@1.5.0#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'); + } + if (this.currentList && this.currentList[offPatchesSymbol]) { + this.currentList[offPatchesSymbol](this.onPatchesNotify, '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.8#lib/list*/ +define('can-view-live@4.2.8#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.8#lib/text*/ +define('can-view-live@4.2.8#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.8#can-view-live*/ +define('can-view-live@4.2.8#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.17.21#src/text_section*/ +define('can-stache@4.17.21#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.17.21#expressions/arg*/ +define('can-stache@4.17.21#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.17.21#expressions/literal*/ +define('can-stache@4.17.21#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.5.0#setter/setter*/ +define('can-simple-observable@2.5.0#setter/setter', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-observation', + '../settable/settable', + 'can-event-queue/value/value', + 'can-symbol' +], 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'); + var canSymbol = require('can-symbol'); + var setElementSymbol = canSymbol.for('can.setElement'); + 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, + 'can.setElement': function (el) { + this.observation[setElementSymbol](el); + } + }); + module.exports = SetterObservable; +}); +/*can-stache@4.17.21#src/expression-helpers*/ +define('can-stache@4.17.21#src/expression-helpers', [ + 'require', + 'exports', + 'module', + '../expressions/arg', + '../expressions/literal', + 'can-reflect', + 'can-stache-key', + 'can-observation', + 'can-observation-recorder', + '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 Observation = require('can-observation'); + var ObservationRecorder = require('can-observation-recorder'); + var makeComputeLike = require('can-view-scope/make-compute-like'); + var SetterObservable = require('can-simple-observable/setter/setter'); + 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 = ObservationRecorder.peekValue(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_fromDynamicKey_fromObservable: getObservableValue_fromDynamicKey_fromObservable, + convertToArgExpression: convertToArgExpression, + toComputeOrValue: toComputeOrValue, + toCompute: toCompute + }; +}); +/*can-stache@4.17.21#expressions/hashes*/ +define('can-stache@4.17.21#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.17.21#expressions/bracket*/ +define('can-stache@4.17.21#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.17.21#src/set-identifier*/ +define('can-stache@4.17.21#src/set-identifier', function (require, exports, module) { + 'use strict'; + module.exports = function SetIdentifier(value) { + this.value = value; + }; +}); +/*can-stache@4.17.21#expressions/call*/ +define('can-stache@4.17.21#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', + 'can-observation' +], 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 Observation = require('can-observation'); + 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 }); + Observation.temporarilyBind(method); + var 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') { + if (canReflect.isObservableLike(func)) { + func = canReflect.getValue(func); + } + 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.17.21#expressions/helper*/ +define('can-stache@4.17.21#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 = scope.computeData(methodKey, { 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; + }; + module.exports = Helper; +}); +/*can-stache@4.17.21#expressions/lookup*/ +define('can-stache@4.17.21#expressions/lookup', [ + 'require', + 'exports', + 'module', + '../src/expression-helpers', + 'can-reflect', + 'can-symbol', + 'can-assign' +], 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 assign = require('can-assign'); + var Lookup = function (key, root, sourceText) { + this.key = key; + this.rootExpr = root; + canReflect.setKeyValue(this, sourceTextSymbol, sourceText); + }; + Lookup.prototype.value = function (scope, readOptions) { + if (this.rootExpr) { + return expressionHelpers.getObservableValue_fromDynamicKey_fromObservable(this.key, this.rootExpr.value(scope), scope, {}, {}); + } else { + return scope.computeData(this.key, assign({ warnOnMissingKey: true }, readOptions)); + } + }; + module.exports = Lookup; +}); +/*can-stache@4.17.21#src/expression*/ +define('can-stache@4.17.21#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(); + lastToken = stack.topLastChild(); + if (top.type === 'Lookup') { + stack.replaceTopAndPush({ + type: 'Call', + method: convertToAtLookup(top) + }); + } else if (lastToken && lastToken.type === 'Call') { + stack.replaceTopAndPush({ + type: 'Call', + method: lastToken + }); + } 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.17.21#src/mustache_core*/ +define('can-stache@4.17.21#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.Literal) { + value = exprData.value.bind(exprData); + } 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; + var partialScope = scope; + if (exprData && exprData.argExprs.length === 1) { + var newContext = canReflect.getValue(exprData.argExprs[0].value(scope)); + if (typeof newContext === 'undefined') { + } else { + partialScope = scope.add(newContext); + } + } + var partial = canReflect.getKeyValue(partialScope.templateContext.partials, localPartialName); + var renderer; + if (partial) { + renderer = function () { + return partial.render ? partial.render(partialScope, nodeList) : partial(partialScope); + }; + } else { + var scopePartialName = partialScope.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(partialScope, {}, nodeList); + } else { + var domRenderer = core.getTemplateById(localPartialName); + return domRenderer ? domRenderer(partialScope, {}, 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(); + } + if (res == null) { + return ''; + } + return res.nodeType === 11 ? res.textContent : '' + res; + }; + branchRenderer.exprData = exprData; + return branchRenderer; + }, + makeLiveBindingBranchRenderer: function (mode, expressionString, state) { + var exprData = core.expression.parse(expressionString); + 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, '$1$2'); + }, + getTemplateById: function () { + } + }; + var makeEvaluator = core.makeEvaluator, splitModeFromExpression = core.splitModeFromExpression; + module.exports = core; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-globals@1.2.2#base-url/base-url*/ +define('can-globals@1.2.2#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.2#can-parse-uri*/ +define('can-parse-uri@1.2.2#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.17.21#helpers/-debugger*/ +define('can-stache@4.17.21#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.17.21#src/truthy-observable*/ +define('can-stache@4.17.21#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-stache@4.17.21#helpers/converter*/ +define('can-stache@4.17.21#helpers/converter', [ + 'require', + 'exports', + 'module', + '../src/set-identifier', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + 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]; + } + }; + } + module.exports = makeConverter; +}); +/*can-stache@4.17.21#helpers/-for-of*/ +define('can-stache@4.17.21#helpers/-for-of', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-observation', + 'can-view-live', + 'can-view-nodelist', + '../src/expression', + '../src/key-observable' +], function (require, exports, module) { + 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.replace(/\./g, '\\.')); + 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; + }; + module.exports = forHelper; +}); +/*can-stache@4.17.21#helpers/-let*/ +define('can-stache@4.17.21#helpers/-let', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-observation-recorder' +], function (require, exports, module) { + var canReflect = require('can-reflect'); + var ObservationRecorder = require('can-observation-recorder'); + function isVariable(scope) { + return scope._meta.variable === true; + } + var letHelper = ObservationRecorder.ignore(function (options) { + if (options.isSection) { + return options.fn(options.scope.addLetContext(options.hash)); + } + 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(''); + }); + module.exports = letHelper; +}); +/*can-stache@4.17.21#helpers/-portal*/ +define('can-stache@4.17.21#helpers/-portal', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-view-live', + 'can-view-nodelist', + 'can-observation', + 'can-globals/document/document', + 'can-dom-mutate', + 'can-dom-mutate/node', + 'can-symbol' +], function (require, exports, module) { + (function (global, require, exports, module) { + var canReflect = require('can-reflect'); + var live = require('can-view-live'); + var nodeLists = require('can-view-nodelist'); + var Observation = require('can-observation'); + var getDocument = require('can-globals/document/document'); + var domMutate = require('can-dom-mutate'); + var domMutateNode = require('can-dom-mutate/node'); + var canSymbol = require('can-symbol'); + var keepNodeSymbol = canSymbol.for('done.keepNode'); + function portalHelper(elementObservable, options) { + function evaluator() { + var frag = options.fn(options.scope.addLetContext({}), options.options); + var child = frag.firstChild; + while (child) { + child[keepNodeSymbol] = true; + child = child.nextSibling; + } + return frag; + } + var el, nodeList, removeNodeRemovalListener; + function teardown() { + var root = el; + if (removeNodeRemovalListener) { + removeNodeRemovalListener(); + removeNodeRemovalListener = null; + } + if (el) { + canReflect.offValue(elementObservable, getElementAndRender); + el = null; + } + if (nodeList) { + canReflect.eachListLike(nodeList, function (node) { + if (root === node.parentNode) { + domMutateNode.removeChild.call(root, node); + } + }); + nodeList = null; + } + } + function getElementAndRender() { + teardown(); + el = canReflect.getValue(elementObservable); + if (el) { + var node = getDocument().createTextNode(''); + domMutateNode.appendChild.call(el, node); + nodeList = [node]; + nodeList.expression = 'live.html'; + nodeLists.register(nodeList, null, null, true); + var observable = new Observation(evaluator, null, { isObservable: false }); + live.html(node, observable, el, nodeList); + removeNodeRemovalListener = domMutate.onNodeRemoval(el, teardown); + } else { + options.metadata.rendered = true; + } + canReflect.onValue(elementObservable, getElementAndRender); + } + getElementAndRender(); + return function (el) { + var doc = getDocument(); + var comment = doc.createComment('portal(' + canReflect.getName(elementObservable) + ')'); + var frag = doc.createDocumentFragment(); + domMutateNode.appendChild.call(frag, comment); + nodeLists.replace([el], frag); + var nodeList = [comment]; + nodeList.expression = 'portal'; + nodeLists.register(nodeList, teardown, options.nodeList, true); + nodeLists.update(options.nodeList, [comment]); + }; + } + portalHelper.isLiveBound = true; + portalHelper.requiresOptionsArgument = true; + module.exports = portalHelper; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-stache@4.17.21#helpers/core*/ +define('can-stache@4.17.21#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', + './converter', + 'can-dom-data', + './-for-of', + './-let', + './-portal' +], 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 makeConverter = require('./converter'); + var domData = require('can-dom-data'); + var forHelper = require('./-for-of'); + var letHelper = require('./-let'); + var portalHelper = require('./-portal'); + var builtInHelpers = {}; + var builtInConverters = {}; + var converterPackages = new WeakMap(); + 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)); + } + }, + registerConverter: function (name, getterSetter) { + helpersCore.registerHelper(name, makeConverter(getterSetter)); + }, + 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)); + }, + addConverter: function (name, getterSetter) { + if (typeof name === 'object') { + if (!converterPackages.has(name)) { + converterPackages.set(name, true); + canReflect.eachKey(name, function (getterSetter, name) { + helpersCore.addConverter(name, getterSetter); + }); + } + return; + } + var helper = makeConverter(getterSetter); + helper.isLiveBound = true; + helpersCore.registerHelper(name, helper); + }, + 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]; + } + converterPackages.delete(builtInConverters); + helpersCore.addBuiltInHelpers(); + helpersCore.addBuiltInConverters(); + }, + addBuiltInHelpers: function () { + canReflect.each(builtInHelpers, function (helper, helperName) { + helpers[helperName] = helper; + }); + }, + addBuiltInConverters: function () { + helpersCore.addConverter(builtInConverters); + }, + _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 (options) { + return value ? options.fn(options.scope || this) : options.inverse(options.scope || this); + } + return !!value; + }, { + 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); + } + }; + 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) { + domData.set(el, attr, data); + }; + }; + var unlessHelper = function (expr, options) { + if (!options) { + return !ifHelper.apply(this, [expr]); + } + return ifHelper.apply(this, [ + expr, + assign(assign({}, options), { + fn: options.inverse, + inverse: options.fn + }) + ]); + }; + unlessHelper.requiresOptionsArgument = true; + unlessHelper.isLiveBound = true; + var notConverter = { + get: function (obs, options) { + if (helpersCore.looksLikeOptions(options)) { + return canReflect.getValue(obs) ? options.inverse() : options.fn(); + } else { + return !canReflect.getValue(obs); + } + }, + set: function (newVal, obs) { + canReflect.setValue(obs, !newVal); + } + }; + assign(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, + 'let': letHelper, + 'for': forHelper, + portal: portalHelper + }); + assign(builtInConverters, { 'not': notConverter }); + helpersCore.addBuiltInHelpers(); + helpersCore.addBuiltInConverters(); + module.exports = helpersCore; + }(function () { + return this; + }(), require, exports, module)); +}); +/*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.17.21#can-stache*/ +define('can-stache@4.17.21#can-stache', [ + 'require', + 'exports', + 'module', + 'can-view-parser', + 'can-view-callbacks', + './src/html_section', + './src/text_section', + './src/mustache_core', + './helpers/core', + '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'); + 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-bind@1.5.1#can-bind*/ +define('can-bind@1.5.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 onEmitSymbol = canSymbol.for('can.onEmit'); + var offEmitSymbol = canSymbol.for('can.offEmit'); + var setValueSymbol = canSymbol.for('can.setValue'); + var canElementSymbol = canSymbol.for('can.element'); + function defaultSetValue(newValue, observable) { + canReflect.setValue(observable, newValue); + } + function onEmit(listenToObservable, updateFunction, queue) { + return listenToObservable[onEmitSymbol](updateFunction, queue); + } + function offEmit(listenToObservable, updateFunction, queue) { + return listenToObservable[offEmitSymbol](updateFunction, queue); + } + function turnOffListeningAndUpdate(listenToObservable, updateObservable, updateFunction, queue) { + var offValueOrOffEmitFn; + if (listenToObservable[onValueSymbol]) { + offValueOrOffEmitFn = canReflect.offValue; + } else if (listenToObservable[onEmitSymbol]) { + offValueOrOffEmitFn = offEmit; + } + if (offValueOrOffEmitFn) { + offValueOrOffEmitFn(listenToObservable, updateFunction, queue); + } + } + function turnOnListeningAndUpdate(listenToObservable, updateObservable, updateFunction, queue) { + var onValueOrOnEmitFn; + if (listenToObservable[onValueSymbol]) { + onValueOrOnEmitFn = canReflect.onValue; + } else if (listenToObservable[onEmitSymbol]) { + onValueOrOnEmitFn = onEmit; + } + if (onValueOrOnEmitFn) { + onValueOrOnEmitFn(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) { + if (options.element) { + options.queue = 'dom'; + } else { + options.queue = 'domUI'; + } + } + if (options.cycles > 0 === false) { + options.cycles = 0; + } + options.onInitDoNotUpdateChild = typeof options.onInitDoNotUpdateChild === 'boolean' ? options.onInitDoNotUpdateChild : false; + options.onInitDoNotUpdateParent = typeof options.onInitDoNotUpdateParent === 'boolean' ? options.onInitDoNotUpdateParent : 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); + if (options.element) { + this._updateChild[canElementSymbol] = this._updateParent[canElementSymbol] = options.element; + } + } + 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.onInitDoNotUpdateParent === false && options.onInitSetUndefinedParentIfChildIsDefined === true) { + this._updateParent(childValue); + } + } else { + if (options.onInitDoNotUpdateChild === false) { + this._updateChild(parentValue); + } + } + } else if (this._childToParent === true) { + if (options.onInitDoNotUpdateParent === false) { + 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); + } + } + }); + [ + 'parent', + 'child' + ].forEach(function (property) { + Object.defineProperty(Bind.prototype, property, { + get: function () { + return this._options[property]; + } + }); + }); + 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.3#can-view-model*/ +define('can-view-model@4.0.3#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.2.7#event*/ +define('can-attribute-observable@1.2.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.2.7#get-event-name*/ +define('can-attribute-observable@1.2.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'; + }; + module.exports = function getEventName(el, prop) { + var event = 'change'; + if (isRadioInput(el) && prop === 'checked') { + event = 'can-attribute-observable-radiochange'; + } + if (attr.findSpecialListener(prop)) { + event = prop; + } + return event; + }; +}); +/*can-event-dom-radiochange@2.2.1#can-event-dom-radiochange*/ +define('can-event-dom-radiochange@2.2.1#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.2.7#can-attribute-observable*/ +define('can-attribute-observable@1.2.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-symbol', + '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 canSymbol = require('can-symbol'); + var onValueSymbol = canSymbol.for('can.onValue'); + var offValueSymbol = canSymbol.for('can.offValue'); + var onEmitSymbol = canSymbol.for('can.onEmit'); + var offEmitSymbol = canSymbol.for('can.offEmit'); + 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) { + if (typeof bindingData === 'string') { + event = bindingData; + bindingData = undefined; + } + this.el = el; + this.bound = false; + this.prop = isMultipleSelect(el, prop) ? 'values' : prop; + this.event = event || getEventName(el, prop); + this.handler = this.handler.bind(this); + if (event !== undefined) { + this[onValueSymbol] = null; + this[offValueSymbol] = null; + this[onEmitSymbol] = AttributeObservable.prototype.on; + this[offEmitSymbol] = AttributeObservable.prototype.off; + } + } + 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 (event !== undefined || 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.10.9#can-stache-bindings*/ +define('can-stache-bindings@4.10.9#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-view-scope', + 'can-assign', + 'can-log/dev/dev', + 'can-dom-mutate', + 'can-dom-data', + '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-event-queue/map/map' +], function (require, exports, module) { + (function (global, 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 stacheKey = require('can-stache-key'); + var ObservationRecorder = require('can-observation-recorder'); + var SimpleObservable = require('can-simple-observable'); + var Scope = require('can-view-scope'); + var assign = require('can-assign'); + var dev = require('can-log/dev/dev'); + var domMutate = require('can-dom-mutate'); + var domData = require('can-dom-data'); + 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 canEventQueue = require('can-event-queue/map/map'); + 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', viewModelSymbol = canSymbol.for('can.viewModel'); + 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, siblingBindingData) { + var isSettingOnViewModel = siblingBindingData.parent.exports && siblingBindingData.child.source === viewModelBindingStr; + if (isSettingOnViewModel) { + var bindingName = siblingBindingData.child.name; + 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 getEventBindingData = function (attributeName, el, scope) { + var bindingCode = attributeName.substr(onMatchStr.length); + var viewModel = el && el[viewModelSymbol]; + var elUsed = startsWith.call(bindingCode, elMatchStr); + var vmUsed = startsWith.call(bindingCode, vmMatchStr); + var byUsed = bindingCode.indexOf(byMatchStr) > -1; + var scopeUsed; + var bindingContext; + var eventName; + var bindingContextObservable; + var shortBindingCode = ''; + if (vmUsed) { + shortBindingCode = 'vm'; + bindingCode = bindingCode.substr(vmMatchStr.length); + } else if (elUsed) { + shortBindingCode = 'el'; + bindingCode = bindingCode.substr(elMatchStr.length); + } else if (!vmUsed && !elUsed) { + if (byUsed) { + scopeUsed = true; + } else if (viewModel) { + vmUsed = true; + } else { + elUsed = true; + } + } + var bindingContextKey; + if (byUsed) { + var byIndex = bindingCode.indexOf(byMatchStr); + bindingContextKey = bindingCode.substr(byIndex + byMatchStr.length); + bindingCode = bindingCode.substr(0, byIndex); + } + eventName = bindingCode; + if (elUsed) { + if (byUsed) { + throw new Error('binding with :by in element scope is not currently supported'); + } else { + bindingContext = el; + } + } else if (vmUsed) { + bindingContext = viewModel; + if (byUsed) { + bindingContext = viewModel.get(bindingContextKey); + bindingContextObservable = new Scope(viewModel).computeData(bindingContextKey); + } + } else if (scopeUsed) { + bindingContext = scope; + if (byUsed) { + bindingContext = bindingContext.get(bindingContextKey); + bindingContextObservable = scope.computeData(bindingContextKey); + } + } + return { + bindingContext: bindingContext, + bindingContextObservable: bindingContextObservable, + eventName: eventName, + bindingCode: shortBindingCode + }; + }; + var onKeyValueSymbol = canSymbol.for('can.onKeyValue'); + var makeScopeFromEvent = function (element, event, viewModel, args, data, bindingContext) { + var shiftArgumentsForLegacyArguments = bindingContext && bindingContext[onKeyValueSymbol] !== undefined; + var specialValues = { + element: element, + event: event, + viewModel: viewModel, + arguments: shiftArgumentsForLegacyArguments ? Array.prototype.slice.call(args, 1) : args, + args: 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 = { + initializeViewModel: function (bindings, initialViewModelData, makeViewModel, bindingContext) { + var onCompleteBindings = [], onTeardowns = {}; + var bindingsState = { + isSettingOnViewModel: false, + isSettingViewModel: false, + initialViewModelData: initialViewModelData || {} + }; + bindings.forEach(function (dataBinding) { + dataBinding.binding.startParent(); + var siblingBindingData = dataBinding.siblingBindingData; + bindingsState = checkBindingState(bindingsState, siblingBindingData); + if (siblingBindingData.parent.exports) { + var parentValue = siblingBindingData.child.setCompute ? makeCompute(dataBinding.binding.parent) : dataBinding.binding.parentValue; + if (parentValue !== undefined) { + if (bindingsState.isSettingViewModel) { + bindingsState.initialViewModelData = parentValue; + } else { + bindingsState.initialViewModelData[cleanVMName(siblingBindingData.child.name, bindingContext.scope)] = parentValue; + } + } + } + onCompleteBindings.push(dataBinding.binding.start.bind(dataBinding.binding)); + onTeardowns[siblingBindingData.bindingAttributeName] = dataBinding.binding.stop.bind(dataBinding.binding); + }); + var viewModel = makeViewModel(bindingsState.initialViewModelData, bindings.length > 0, bindingsState); + for (var i = 0, len = onCompleteBindings.length; i < len; i++) { + onCompleteBindings[i](); + } + return { + viewModel: viewModel, + onTeardowns: onTeardowns, + bindingsState: bindingsState + }; + }, + viewModel: function (el, tagData, makeViewModel, initialViewModelData, staticDataBindingsOnly) { + var attributeViewModelBindings = assign({}, initialViewModelData), bindingContext = assign({ + element: el, + viewModel: undefined + }, tagData), bindingSettings = { + attributeViewModelBindings: attributeViewModelBindings, + alreadyUpdatedChild: true, + favorViewModel: true + }, dataBindings = []; + canReflect.eachListLike(el.attributes || [], function (node) { + var dataBinding = makeDataBinding(node, bindingContext, bindingSettings); + if (dataBinding) { + dataBindings.push(dataBinding); + } + }); + if (staticDataBindingsOnly && dataBindings.length === 0) { + return; + } + var completedData = behaviors.initializeViewModel(dataBindings, initialViewModelData, function () { + bindingContext.viewModel = makeViewModel.apply(this, arguments); + }, bindingContext), onTeardowns = completedData.onTeardowns, bindingsState = completedData.bindingsState, siblingBindingDatas = {}; + var attributeDisposal; + if (!bindingsState.isSettingViewModel) { + bindingSettings.alreadyUpdatedChild = false; + attributeDisposal = domMutate.onNodeAttributeChange(el, function (ev) { + var attrName = ev.attributeName, value = el.getAttribute(attrName); + if (onTeardowns[attrName]) { + onTeardowns[attrName](); + } + var parentBindingWasAttribute = siblingBindingDatas[attrName] && siblingBindingDatas[attrName].parent.source === attributeBindingStr; + if (value !== null || parentBindingWasAttribute) { + var dataBinding = makeDataBinding({ + name: attrName, + value: value + }, bindingContext, bindingSettings); + if (dataBinding) { + dataBinding.binding.start(); + siblingBindingDatas[attrName] = dataBinding.siblingBindingData; + onTeardowns[attrName] = dataBinding.binding.stop.bind(dataBinding.binding); + } + } + }); + } + return function () { + if (attributeDisposal) { + attributeDisposal(); + attributeDisposal = undefined; + } + for (var attrName in onTeardowns) { + onTeardowns[attrName](); + } + }; + }, + data: function (el, attrData) { + if (domData.get(el, 'preventDataBindings')) { + return; + } + var viewModel, getViewModel = ObservationRecorder.ignore(function () { + return viewModel || (viewModel = canViewModel(el)); + }), teardown, attributeDisposal, removedDisposal, bindingContext = { + element: el, + templateType: attrData.templateType, + scope: attrData.scope, + parentNodeList: attrData.nodeList, + get viewModel() { + return getViewModel(); + } + }; + var dataBinding = makeDataBinding({ + name: attrData.attributeName, + value: el.getAttribute(attrData.attributeName) + }, bindingContext, { syncChildWithParent: false }); + dataBinding.binding.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 + }, bindingContext, { syncChildWithParent: false }); + if (dataBinding) { + dataBinding.binding.start(); + teardown = dataBinding.binding.stop.bind(dataBinding.binding); + } + 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.binding.stop.bind(dataBinding.binding); + 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 eventBindingData; + var attributeName = encoder.decode(data.attributeName), event, bindingContext, bindingContextObservable; + if (attributeName.indexOf(toMatchStr + ':') !== -1 || attributeName.indexOf(fromMatchStr + ':') !== -1 || attributeName.indexOf(bindMatchStr + ':') !== -1) { + return this.data(el, data); + } + if (startsWith.call(attributeName, onMatchStr)) { + eventBindingData = getEventBindingData(attributeName, el, data.scope); + event = eventBindingData.eventName; + bindingContext = eventBindingData.bindingContext; + bindingContextObservable = eventBindingData.bindingContextObservable; + } 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 = el[viewModelSymbol]; + var expr = expression.parse(attrVal, { + lookupRule: function () { + return expression.Lookup; + }, + methodRule: 'call' + }); + var runScope = makeScopeFromEvent(el, ev, viewModel, arguments, data, bindingContext); + 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, removeObservation, currentContext; + 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 () { + if (bindingContext) { + canEventQueue.off.call(bindingContext, event, handler); + } + if (attributesDisposal) { + attributesDisposal(); + attributesDisposal = undefined; + } + if (removalDisposal) { + removalDisposal(); + removalDisposal = undefined; + } + if (removeObservation) { + removeObservation(); + removeObservation = undefined; + } + }; + function updateListener(newVal, oldVal) { + if (oldVal) { + canEventQueue.off.call(oldVal, event, handler); + } + if (newVal) { + canEventQueue.on.call(newVal, event, handler); + currentContext = newVal; + } + } + attributesDisposal = domMutate.onNodeAttributeChange(el, attributesHandler); + removalDisposal = domMutate.onNodeRemoval(el, removalHandler); + if (!bindingContext && bindingContextObservable) { + removeObservation = function () { + if (currentContext) { + canEventQueue.off.call(currentContext, event, handler); + } + canReflect.offValue(bindingContextObservable, updateListener); + }; + canReflect.onValue(bindingContextObservable, updateListener); + } else { + canEventQueue.on.call(bindingContext, event, handler); + } + } + }; + 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 (bindingData, bindingContext) { + var viewModel = bindingContext.element[viewModelSymbol]; + if (viewModel) { + return this.viewModel.apply(this, arguments); + } else { + return this.attribute.apply(this, arguments); + } + }, + scope: function (bindingData, bindingContext) { + var scope = bindingContext.scope, scopeProp = bindingData.name, mustBeGettable = bindingData.exports; + 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 (bindingData, bindingContext) { + var scope = bindingContext.scope, vmName = bindingData.name, setCompute = bindingData.setCompute; + var setName = cleanVMName(vmName, scope); + var isBoundToContext = vmName === '.' || vmName === 'this'; + var keysToRead = isBoundToContext ? [] : stacheKey.reads(vmName); + function getViewModelProperty() { + var viewModel = bindingContext.viewModel; + return stacheKey.read(viewModel, keysToRead, {}).value; + } + var observation = new SettableObservable(getViewModelProperty, function setViewModelProperty(newVal) { + var viewModel = bindingContext.viewModel; + if (setCompute) { + var oldValue = canReflect.getKeyValue(viewModel, setName); + if (canReflect.isObservableLike(oldValue)) { + canReflect.setValue(oldValue, newVal); + } else { + canReflect.setKeyValue(viewModel, setName, new SimpleObservable(canReflect.getValue(newVal))); + } + } else { + if (isBoundToContext) { + canReflect.setValue(viewModel, newVal); + } else { + stacheKey.write(viewModel, keysToRead, newVal); + } + } + }); + return observation; + }, + attribute: function (bindingData, bindingContext) { + if (bindingData.name === 'this') { + return canReflect.assignSymbols({}, { + 'can.getValue': function () { + return bindingContext.element; + }, + 'can.valueHasDependencies': function () { + return false; + }, + 'can.getName': function getName() { + } + }); + } else { + return new AttributeObservable(bindingContext.element, bindingData.name, {}, 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 siblingBindingRules = { + to: { + child: { + exports: true, + syncSibling: false + }, + parent: { + exports: false, + syncSibling: false + } + }, + from: { + child: { + exports: false, + syncSibling: false + }, + parent: { + exports: true, + syncSibling: false + } + }, + bind: { + child: { + exports: true, + syncSibling: false + }, + parent: { + exports: true, + syncSibling: true + } + }, + raw: { + child: { + exports: false, + syncSibling: false + }, + parent: { + exports: true, + syncSibling: false + } + } + }; + var bindingNames = []; + var special = { + vm: true, + on: true + }; + canReflect.eachKey(siblingBindingRules, 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; + } + }; + function getSiblingBindingData(node, bindingSettings) { + var siblingBindingData, 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; + siblingBindingData = { + parent: assign({ + source: scopeBindingStr, + name: result.special.raw ? '"' + attributeValue + '"' : attributeValue + }, siblingBindingRules[dataBindingName].parent), + child: assign({ + source: getChildBindingStr(result.tokens, bindingSettings && bindingSettings.favorViewModel), + name: result.tokens[specialIndex - 1], + event: childEventName + }, siblingBindingRules[dataBindingName].child), + bindingAttributeName: attributeName, + initializeValues: initializeValues + }; + if (attributeValue.trim().charAt(0) === '~') { + siblingBindingData.child.setCompute = true; + } + return siblingBindingData; + } + } + var makeDataBinding = function (node, bindingContext, bindingSettings) { + var siblingBindingData = getSiblingBindingData(node, bindingSettings); + if (!siblingBindingData) { + return; + } + var parentObservable = getObservableFrom[siblingBindingData.parent.source](siblingBindingData.parent, bindingContext, bindingSettings), childObservable = getObservableFrom[siblingBindingData.child.source](siblingBindingData.child, bindingContext, bindingSettings, parentObservable); + var childToParent = !!siblingBindingData.child.exports; + var parentToChild = !!siblingBindingData.parent.exports; + var bindingOptions = { + child: childObservable, + childToParent: childToParent, + cycles: childToParent === true && parentToChild === true ? 0 : 100, + onInitDoNotUpdateChild: bindingSettings.alreadyUpdatedChild || siblingBindingData.initializeValues === false, + onInitDoNotUpdateParent: siblingBindingData.initializeValues === false, + onInitSetUndefinedParentIfChildIsDefined: true, + parent: parentObservable, + parentToChild: parentToChild, + priority: bindingContext.parentNodeList ? bindingContext.parentNodeList.nesting + 1 : undefined, + queue: 'domUI', + sticky: siblingBindingData.parent.syncSibling ? 'childSticksToParent' : undefined + }; + var canBinding = new Bind(bindingOptions); + return { + siblingBindingData: siblingBindingData, + binding: canBinding + }; + }; + var cleanVMName = function (name, scope) { + return name.replace(/@/g, ''); + }; + var canStacheBindings = { + behaviors: behaviors, + getSiblingBindingData: getSiblingBindingData, + bindings: bindings, + getObservableFrom: getObservableFrom, + makeDataBinding: makeDataBinding + }; + canStacheBindings[canSymbol.for('can.callbackMap')] = bindings; + viewCallbacks.attrs(canStacheBindings); + module.exports = canStacheBindings; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-simple-observable@2.5.0#async/async*/ +define('can-simple-observable@2.5.0#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.5.0#resolver/resolver*/ +define('can-simple-observable@2.5.0#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'); + var metaSymbol = canSymbol.for('can.meta'); + function ResolverObservable(resolver, context, initialValue, options) { + 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 = {}; + this[metaSymbol] = canReflect.assignMap({}, options); + } + 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 { + if (this[metaSymbol].resetUnboundValueInGet) { + this._value = undefined; + } + 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[metaSymbol]; + 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.7#type/type*/ +define('can-event-queue@1.1.7#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.1#can-string-to-any*/ +define('can-string-to-any@1.2.1#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.1#maybe-boolean/maybe-boolean*/ +define('can-data-types@1.2.1#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.1#maybe-date/maybe-date*/ +define('can-data-types@1.2.1#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.1#maybe-number/maybe-number*/ +define('can-data-types@1.2.1#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.1#maybe-string/maybe-string*/ +define('can-data-types@1.2.1#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.8.0#can-define*/ +define('can-define@2.8.0#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'), inSetupSymbol = canSymbol.for('can.initializing'); + 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); + if (definition.get.length === 0) { + } + } 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({ + action: 'can.keys', + type: 'can.keys', + target: this.prototype + }); + }; + }; + define.Constructor = function (defines, sealed) { + var constructor = function DefineConstructor(props) { + Object.defineProperty(this, inSetupSymbol, { + configurable: true, + enumerable: false, + value: true, + writable: true + }); + define.setup.call(this, props, sealed); + this[inSetupSymbol] = 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({ + action: 'set', + key: 'prop', + target: map, + value: newVal, + oldValue: oldValue, + type: prop + }, [ + 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[inSetupSymbol]) { + setData.call(this, newVal); + } else { + var current = getCurrent.call(this); + if (newVal === current) { + return; + } + var dispatched; + setData.call(this, newVal); + dispatched = { + patches: [{ + type: 'set', + key: prop, + value: newVal + }], + target: this, + action: 'set', + value: newVal, + oldValue: current, + key: prop, + type: prop + }; + 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[inSetupSymbol]) { + 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; + 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 if (defaultDefinition.Type && canReflect.isConstructorLike(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[inSetupSymbol]) { + queues.batch.start(); + map.dispatch({ + action: 'can.keys', + target: map, + type: 'can.keys' + }); + if (Object.prototype.hasOwnProperty.call(map._data, prop)) { + map.dispatch({ + action: 'add', + target: map, + value: map._data[prop], + oldValue: undefined, + key: prop, + type: prop, + patches: [{ + type: 'add', + key: prop, + value: map._data[prop] + }] + }, [ + map._data[prop], + undefined + ]); + } else { + map.dispatch({ + type: 'set', + target: map, + patches: [{ + type: 'add', + 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 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.8.0#ensure-meta*/ +define('can-define@2.8.0#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.8.0#define-helpers/define-helpers*/ +define('can-define@2.8.0#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({ + action: 'can.keys', + type: 'can.keys', + target: this + }); + var oldValue = this._data[prop]; + if (oldValue !== undefined) { + delete this._data[prop]; + this.dispatch({ + action: 'delete', + key: prop, + value: undefined, + oldValue: oldValue, + 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.8.0#map/map*/ +define('can-define@2.8.0#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) || this._instanceDefinitions !== undefined && Object.hasOwnProperty.call(this._instanceDefinitions, key); + }, + 'can.hasKey': function (key) { + return key in this._define.definitions || this._instanceDefinitions !== undefined && key in this._instanceDefinitions; + }, + '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 + }); + } + function getSymbolsForIE(obj) { + return Object.getOwnPropertyNames(obj).filter(function (name) { + return name.indexOf('@@symbol') === 0; + }); + } + var eventsProtoSymbols = 'getOwnPropertySymbols' in Object ? Object.getOwnPropertySymbols(define.eventsProto) : getSymbolsForIE(define.eventsProto); + 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-key@1.2.1#utils*/ +define('can-key@1.2.1#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.1#get/get*/ +define('can-key@1.2.1#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.3#can-control*/ +define('can-control@4.4.3#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.6.2#control/control*/ +define('can-component@4.6.2#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-define@2.8.0#list/list*/ +define('can-define@2.8.0#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'); + var inSetupSymbol = canSymbol.for('can.initializing'); + 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, + action: 'splice', + insert: newVal, + index: index, + deleteCount: 0, + 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, + action: 'splice', + index: index, + deleteCount: oldVal.length, + target: this + }; + 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, { + includes: function () { + var arrayIncludes = Array.prototype.includes; + if (arrayIncludes) { + return function includes() { + return arrayIncludes.apply(this, arguments); + }; + } else { + return function includes() { + throw new Error('DefineList.prototype.includes must have Array.prototype.includes available. Please add a polyfill to this environment.'); + }; + } + }(), + 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[inSetupSymbol]) { + 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.6.2#can-component*/ +define('can-component@4.6.2#can-component', [ + 'require', + 'exports', + 'module', + 'can-namespace', + 'can-bind', + 'can-construct', + 'can-stache', + 'can-stache-bindings', + 'can-view-scope', + 'can-view-callbacks', + 'can-view-nodelist', + 'can-reflect', + 'can-simple-observable', + 'can-simple-map', + 'can-define/map/map', + 'can-log', + 'can-log/dev/dev', + 'can-assign', + 'can-observation-recorder', + 'can-queues', + 'can-dom-data', + 'can-child-nodes', + 'can-string', + 'can-dom-events', + 'can-dom-mutate', + 'can-dom-mutate/node', + 'can-symbol', + 'can-globals/document/document', + './control/control', + 'can-view-model', + 'can-define/list/list' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + 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 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'); + var queues = require('can-queues'); + var domData = require('can-dom-data'); + 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 ComponentControl = require('./control/control'); + require('can-view-model'); + require('can-define/list/list'); + stache.addBindings(stacheBindings); + 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'); + var noop = function () { + }; + function addContext(el, tagData, insertionElementTagData) { + var vm, newScope; + domData.set(el, 'preventDataBindings', true); + var teardown = stacheBindings.behaviors.viewModel(el, insertionElementTagData, function createViewModel(initialData, hasDataBinding, bindingState) { + if (bindingState && bindingState.isSettingOnViewModel === true) { + newScope = tagData.scope.addLetContext(initialData); + return newScope._context; + } else { + return vm = new SimpleObservable(initialData); + } + }, undefined, true); + if (!teardown) { + return tagData; + } else { + return assign(assign({}, tagData), { + teardown: teardown, + scope: newScope || tagData.scope.add(vm) + }); + } + } + function makeReplacementTagCallback(tagName, componentTagData, shadowTagData, leakScope, getPrimaryTemplate) { + var options = shadowTagData.options; + return function replacementTag(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], tagData.teardown || noop, 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] = replacementTag; + } + }; + } + function getSetupFunctionForComponentVM(componentInitVM) { + return ObservationRecorder.ignore(function (el, componentTagData, makeViewModel, initialVMData) { + var bindingContext = { + element: el, + scope: componentTagData.scope, + parentNodeList: componentTagData.parentNodeList, + viewModel: undefined + }; + var bindingSettings = {}; + var bindings = []; + canReflect.eachKey(componentInitVM, function (parent, propName) { + var canGetParentValue = parent != null && !!parent[getValueSymbol]; + var canSetParentValue = parent != null && !!parent[setValueSymbol]; + if (canGetParentValue === true || canSetParentValue) { + var child = stacheBindings.getObservableFrom.viewModel({ name: propName }, bindingContext, bindingSettings); + var canBinding = new Bind({ + child: child, + parent: parent, + queue: 'domUI' + }); + bindings.push({ + binding: canBinding, + siblingBindingData: { + parent: { + source: 'scope', + exports: canGetParentValue + }, + child: { + source: 'viewModel', + exports: canSetParentValue, + name: propName + } + } + }); + } else { + initialVMData[propName] = parent; + } + }); + var initializeData = stacheBindings.behaviors.initializeViewModel(bindings, initialVMData, function (properties) { + return bindingContext.viewModel = makeViewModel(properties); + }, bindingContext); + return function () { + for (var attrName in initializeData.onTeardowns) { + initializeData.onTeardowns[attrName](); + } + }; + }); + } + 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.view = this.prototype.template; + } + if (this.prototype.view) { + this.view = this.prototype.view; + } + if (typeof this.view === 'string') { + var viewName = string.capitalize(string.camelize(this.prototype.tag)) + 'View'; + this.view = stache(viewName, this.view); + } + this.renderer = this.view; + var renderComponent = function (el, tagData) { + if (el[createdByCanComponentSymbol] === undefined) { + new self(el, tagData); + } + }; + viewCallbacks.tag(this.prototype.tag, renderComponent); + } + } + }, { + 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; + if (componentTagData.initializeBindings === false && !this._skippedSetup) { + this._skippedSetup = this._torndown = true; + this.viewModel = Object.create(null); + return; + } + 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 viewModel; + var initialViewModelData = {}; + var preventDataBindings = domData.get(el, 'preventDataBindings'); + var teardownBindings; + if (preventDataBindings) { + viewModel = el[viewModelSymbol]; + } else { + var setupFn; + if (componentTagData.setupBindings) { + setupFn = function (el, componentTagData, callback, initialViewModelData) { + return componentTagData.setupBindings(el, callback, initialViewModelData); + }; + } else if (componentTagData.viewModel) { + setupFn = getSetupFunctionForComponentVM(componentTagData.viewModel); + } else { + setupFn = stacheBindings.behaviors.viewModel; + } + teardownBindings = setupFn(el, componentTagData, 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 ViewModel(initialViewModelData); + } + viewModel = viewModelInstance; + return viewModelInstance; + }, initialViewModelData); + } + this.viewModel = viewModel; + el[viewModelSymbol] = viewModel; + el.viewModel = viewModel; + domData.set(el, 'preventDataBindings', true); + var teardownFunctions = []; + var callTeardownFunctions = function () { + for (var i = 0, len = teardownFunctions.length; i < len; i++) { + teardownFunctions[i](); + } + }; + 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)) { + if (removalDisposal) { + nodeRemoved = true; + removalDisposal(); + callTeardownFunctions(); + removalDisposal = null; + callTeardownFunctions = null; + } + } + }); + } + var leakScope = { + toLightContent: this.leakScope === true, + intoShadowContent: this.leakScope === true + }; + var hasShadowView = !!this.constructor.view; + var shadowFragment; + var betweenTagsView; + var betweenTagsTagData; + if (hasShadowView) { + 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'] = makeReplacementTagCallback('can-slot', componentTagData, shadowTagData, leakScope, function (el) { + var templates = componentTagData.templates; + if (templates) { + return templates[el.getAttribute('name')]; + } + }); + options.tags.content = makeReplacementTagCallback('content', componentTagData, shadowTagData, leakScope, function () { + return componentTagData.subtemplate; + }); + betweenTagsView = this.constructor.view; + betweenTagsTagData = shadowTagData; + } else { + var lightTemplateTagData = { + scope: componentTagData.scope.add(this.viewModel, { viewModel: true }), + options: options + }; + betweenTagsTagData = lightTemplateTagData; + betweenTagsView = componentTagData.subtemplate || el.ownerDocument.createDocumentFragment.bind(el.ownerDocument); + } + var viewModelDisconnectedCallback, insertionDisposal, componentInPage, nodeRemoved; + var nodeList = nodeLists.register([], function () { + if (removalDisposal && !nodeRemoved) { + removalDisposal(); + callTeardownFunctions(); + removalDisposal = null; + callTeardownFunctions = null; + } + component._torndown = true; + domEvents.dispatch(el, 'beforeremove', false); + if (teardownBindings) { + teardownBindings(); + } + if (viewModelDisconnectedCallback) { + viewModelDisconnectedCallback(el); + } else if (typeof viewModel.stopListening === 'function') { + viewModel.stopListening(); + } + if (insertionDisposal) { + insertionDisposal(); + insertionDisposal = null; + } + }, componentTagData.parentNodeList || true, false); + nodeList.expression = '<' + this.tag + '>'; + teardownFunctions.push(function () { + nodeLists.unregister(nodeList); + }); + this.nodeList = nodeList; + shadowFragment = betweenTagsView(betweenTagsTagData.scope, betweenTagsTagData.options, nodeList); + domMutateNode.appendChild.call(el, shadowFragment); + nodeLists.update(nodeList, getChildNodes(el)); + if (viewModel && viewModel.connectedCallback) { + var body = DOCUMENT().body; + componentInPage = body && body.contains(el); + if (componentInPage) { + viewModelDisconnectedCallback = viewModel.connectedCallback(el); + } else { + insertionDisposal = domMutate.onNodeInsertion(el, function () { + insertionDisposal(); + insertionDisposal = null; + viewModelDisconnectedCallback = 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.6.2#test/component-tag-test*/ +define('can-component@4.6.2#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 (assert) { + Component.extend({ + tag: 'foobar', + view: stache('
      {{name}}
      '), + viewModel: function () { + return new SimpleMap({ name: 'Brian' }); + } + }); + var renderer = stache(''); + var frag = renderer(); + assert.equal(frag.lastChild.firstChild.firstChild.nodeValue, 'Brian'); + }); + }); +}); +/*can-component@4.6.2#test/component-viewmodel-test*/ +define('can-component@4.6.2#test/component-viewmodel-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-dom-data', + './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'); + 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 (assert) { + var map = new SimpleMap({ name: 'Matthew' }); + Component.extend({ + tag: 'can-map-viewmodel', + view: stache('{{name}}'), + ViewModel: function () { + return map; + } + }); + var renderer = stache(''); + assert.equal(renderer().firstChild.firstChild.nodeValue, 'Matthew'); + }); + QUnit.test('a SimpleMap as viewModel', function (assert) { + var me = new SimpleMap({ name: 'Justin' }); + Component.extend({ + tag: 'my-viewmodel', + view: stache('{{name}}}'), + viewModel: me + }); + var renderer = stache(''); + assert.equal(renderer().firstChild.firstChild.nodeValue, 'Justin'); + }); + QUnit.test('a SimpleMap constructor as viewModel', function (assert) { + 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(''); + assert.equal(renderer().firstChild.firstChild.nodeValue, 'Matthew'); + }); + QUnit.test('an object is turned into a SimpleMap as viewModel', function (assert) { + 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'); + assert.equal(fragOne.firstChild.firstChild.nodeValue, 'Wilbur', 'The first map changed values'); + assert.equal(fragTwo.firstChild.firstChild.nodeValue, 'Matthew', 'The second map did not change'); + }); + QUnit.test('Providing viewModel and ViewModel throws', function (assert) { + try { + Component.extend({ + tag: 'viewmodel-test', + view: stache('
      '), + viewModel: {}, + ViewModel: SimpleMap.extend({}) + }); + assert.ok(false, 'Should have thrown because we provided both'); + } catch (er) { + assert.ok(true, 'It threw because we provided both viewModel and ViewModel'); + } + }); + QUnit.test('canViewModel utility', function (assert) { + Component({ + tag: 'my-taggy-tag', + view: stache('

      hello

      '), + viewModel: function () { + return new SimpleMap({ foo: 'bar' }); + } + }); + var frag = stache('')(); + var el = frag.firstChild; + assert.equal(canViewModel(el), el[canSymbol.for('can.viewModel')], 'one argument grabs the viewModel object'); + assert.equal(canViewModel(el, 'foo'), 'bar', 'two arguments fetches a value'); + canViewModel(el, 'foo', 'baz'); + assert.equal(canViewModel(el, 'foo'), 'baz', 'Three arguments sets the value'); + }); + QUnit.test('setting passed variables - two way binding', function (assert) { + 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'); + assert.equal(buttons.length, 1, 'there is one button'); + assert.equal(innerHTML(buttons[0]), 'hide', 'the button\'s text is hide'); + domEvents.dispatch(buttons[0], 'click'); + buttons = myApp.getElementsByTagName('button'); + assert.equal(buttons.length, 1, 'there is one button'); + assert.equal(innerHTML(buttons[0]), 'show', 'the button\'s text is show'); + domEvents.dispatch(buttons[0], 'click'); + buttons = myApp.getElementsByTagName('button'); + assert.equal(buttons.length, 1, 'there is one button'); + assert.equal(innerHTML(buttons[0]), 'hide', 'the button\'s text is hide'); + }); + QUnit.test('don\'t update computes unnecessarily', function (assert) { + var sourceAge = new SimpleObservable(30), timesComputeIsCalled = 0; + var age = new SetterObservable(function () { + timesComputeIsCalled++; + if (timesComputeIsCalled === 1) { + assert.ok(true, 'reading initial value to set as years'); + } else if (timesComputeIsCalled === 3) { + assert.ok(true, 'called back another time after set to get the value'); + } else { + assert.ok(false, '(getter) You\'ve called the callback ' + timesComputeIsCalled + ' times'); + } + return sourceAge.get(); + }, function (newVal) { + timesComputeIsCalled++; + if (timesComputeIsCalled === 2) { + assert.ok(true, 'updating value to ' + newVal); + } else { + assert.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); + }); + QUnit.test('viewModel not rebound correctly (#550)', function (assert) { + 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'); + assert.equal(nameChanges, 2); + }); + QUnit.test('id and class should work now (#694)', function (assert) { + 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); + assert.equal(viewModel.get('id'), 'id-success'); + assert.equal(viewModel.get('class'), 'class-success'); + }); + QUnit.test('Construct are passed normally', function (assert) { + var Constructed = Construct.extend({ foo: 'bar' }, {}); + Component.extend({ + tag: 'con-struct', + view: stache('{{con.foo}}') + }); + var stached = stache(''); + var res = stached({ Constructed: Constructed }); + assert.equal(innerHTML(res.firstChild), 'bar'); + }); + QUnit.test('Component two way binding loop (#1579)', function (assert) { + 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()); + assert.ok(changeCount < 500, 'more than 500 events'); + }); + QUnit.test('two-way binding syntax INTRODUCED in v2.3 ALLOWS a child property to initialize an undefined parent property', function (assert) { + 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); + assert.equal(parentVM.get('parentProp'), 'bar', 'parentProp is bar'); + assert.equal(childVM.get('childProp'), 'bar', 'childProp is bar'); + parentVM.set('parentProp', 'foo'); + assert.equal(parentVM.get('parentProp'), 'foo', 'parentProp is foo'); + assert.equal(childVM.get('childProp'), 'foo', 'childProp is foo'); + childVM.set('childProp', 'baz'); + assert.equal(parentVM.get('parentProp'), 'baz', 'parentProp is baz'); + assert.equal(childVM.get('childProp'), 'baz', 'childProp is baz'); + }); + QUnit.test('conditional attributes (#2077)', function (assert) { + 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 () { + assert.equal(vm.next, 2, 'has binding initially'); + assert.equal(vm.swap, true, 'swap - has binding'); + map.attr('preview', false); + }, + function () { + assert.equal(vm.swap, false, 'swap - updated binidng'); + map.attr('nextPage', 3); + assert.equal(vm.next, 2, 'not updating after binding is torn down'); + map.attr('preview', true); + }, + function () { + assert.equal(vm.next, 3, 're-initialized with binding'); + assert.equal(vm.swap, true, 'swap - updated binidng'); + map.attr('swapName', 'nextPage'); + }, + function () { + assert.equal(vm.swap, 3, 'swap - updated binding key'); + map.attr('nextPage', 4); + assert.equal(vm.swap, 4, 'swap - updated binding'); + } + ]; + var done = assert.async(); + var index = 0; + var next = function () { + if (index < threads.length) { + threads[index](); + index++; + setTimeout(next, 150); + } else { + done(); + } + }; + setTimeout(next, 100); + }); + QUnit.test('one-way - child to parent - parent that does not leak scope, but has no view', function (assert) { + 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); + assert.equal(vm.myChild.name, 'inner', 'got instance'); + }); + QUnit.test('Can be called on an element using preventDataBindings (#183)', function (assert) { + 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(el, 'preventDataBindings', true); + callback(el, { scope: new Scope({ value: 'it did not work' }) }); + canData.set(el, 'preventDataBindings', false); + assert.equal(el.firstChild.nodeValue, 'it worked'); + }); + QUnit.test('viewModel available as viewModel property (#282)', function (assert) { + 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'); + assert.equal(fragOne.firstChild.firstChild.nodeValue, 'Wilbur', 'The first map changed values'); + assert.equal(fragTwo.firstChild.firstChild.nodeValue, 'Matthew', 'The second map did not change'); + }); + QUnit.test('connectedCallback without a disconnect calls stopListening', function (assert) { + assert.expect(1); + var done = assert.async(); + 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 () { + assert.notOk(canReflect.isBound(map), 'stopListening no matter what on vm'); + done(); + }); + }); + }); + }); +}); +/*can-observe@2.3.1#src/-symbols*/ +define('can-observe@2.3.1#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.3.1#src/-observable-store*/ +define('can-observe@2.3.1#src/-observable-store', function (require, exports, module) { + 'use strict'; + module.exports = { + proxiedObjects: new WeakMap(), + proxies: new WeakSet() + }; +}); +/*can-observe@2.3.1#src/-helpers*/ +define('can-observe@2.3.1#src/-helpers', [ + 'require', + 'exports', + 'module', + 'can-globals/global/global', + 'can-symbol' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var getGlobal = require('can-globals/global/global'); + 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; + }, + isBuiltInButNotArrayOrPlainObjectOrElement: function (obj) { + if (obj instanceof getGlobal().Element) { + return false; + } + return helpers.isBuiltInButNotArrayOrPlainObject(obj); + }, + 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; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-observe@2.3.1#src/-computed-helpers*/ +define('can-observe@2.3.1#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.3.1#src/-make-object*/ +define('can-observe@2.3.1#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 && this.options.proxiedPrototype !== true) { + 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) { + 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.3.1#src/-make-array*/ +define('can-observe@2.3.1#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.3.1#src/-make-observe*/ +define('can-observe@2.3.1#src/-make-observe', [ + 'require', + 'exports', + 'module', + 'can-globals/global/global', + 'can-reflect', + './-observable-store', + './-helpers' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var getGlobal = require('can-globals/global/global'); + 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.isBuiltInButNotArrayOrPlainObjectOrElement(value)) { + return value; + } + if (typeof value === 'function') { + observable = makeObserve.function(value); + } else if (helpers.inheritsFromArray(value)) { + observable = makeObserve.array(value); + } else if (value instanceof getGlobal().Element) { + observable = makeObserve.prototype(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; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-observe@2.3.1#src/-make-function*/ +define('can-observe@2.3.1#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.3.1#src/-make-prototype*/ +define('can-observe@2.3.1#src/-make-prototype', [ + 'require', + 'exports', + 'module', + './-make-object', + './-helpers', + './-symbols', + 'can-event-queue/map/map', + 'can-reflect', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var makeObject = require('./-make-object'); + var helpers = require('./-helpers'); + var symbols = require('./-symbols'); + var mapBindings = require('can-event-queue/map/map'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var isSymbolLike = canReflect.isSymbolLike; + var proxyMetaSymbol = canSymbol.for('can.proxyMeta'); + function getMetadata(instance, options) { + if (instance.hasOwnProperty(proxyMetaSymbol)) { + return instance[proxyMetaSymbol]; + } + if (options.shouldRecordObservation === undefined) { + options.shouldRecordObservation = makeObject.shouldRecordObservationOnOwnAndMissingKeys; + } + options.proxiedPrototype = true; + var meta = { + target: makeObject.observable({}, options), + proxyKeys: options.proxyKeys !== undefined ? options.proxyKeys : Object.create(makeObject.proxyKeys()), + computedKeys: Object.create(null), + options: options, + preventSideEffects: 0, + proxy: instance + }; + helpers.assignNonEnumerable(meta.proxyKeys, symbols.metaSymbol, meta); + mapBindings.addHandlers(meta.proxy, meta); + instance[proxyMetaSymbol] = meta; + return meta; + } + var makePrototype = { + observable: function (proto, options) { + var protoProxy = new Proxy(proto, { + set: function (target, key, value, receiver) { + if (isSymbolLike(key) || key in target) { + return Reflect.set(target, key, value, receiver); + } + var meta = getMetadata(receiver, options); + return makeObject.set.call(meta, target, key, value, receiver); + }, + get: function (target, key, receiver) { + if (key in target) { + return Reflect.get(target, key, receiver); + } + var meta = getMetadata(receiver, options); + return makeObject.get.call(meta, target, key, receiver); + } + }); + return protoProxy; + } + }; + module.exports = makePrototype; +}); +/*can-observe@2.3.1#src/-type-helpers*/ +define('can-observe@2.3.1#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.3.1#object/object*/ +define('can-observe@2.3.1#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.3.1#array/array*/ +define('can-observe@2.3.1#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.3.1#decorators/decorators*/ +define('can-observe@2.3.1#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.3.1#can-observe*/ +define('can-observe@2.3.1#can-observe', [ + 'require', + 'exports', + 'module', + './src/-make-object', + './src/-make-array', + './src/-make-function', + './src/-make-observe', + './src/-make-prototype', + './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 makePrototype = require('./src/-make-prototype'); + 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.prototype = function (proto) { + return makePrototype.observable(proto, makeObserve); + }; + makeObserve.array = function (array) { + return makeArray.observable(array, makeObserve); + }; + makeObserve.function = function (fn) { + return makeFunction.observable(fn, 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.6.2#test/component-viewmodel-observe-test*/ +define('can-component@4.6.2#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 (assert) { + 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'); + assert.equal(spans[0].innerHTML, '0', 'first value'); + domEvents.dispatch(buttons[0], 'click'); + assert.equal(spans[0].innerHTML, '1', 'second value'); + }); + if (classSupport) { + QUnit.test('ViewModel as observe(class)', function (assert) { + 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'); + assert.equal(spans[0].innerHTML, '0', 'first value'); + domEvents.dispatch(buttons[0], 'click'); + assert.equal(spans[0].innerHTML, '1', 'second value'); + }); + QUnit.test('connectedCallback and disconnectedCallback', function (assert) { + assert.expect(3); + var done = assert.async(); + Component.extend({ + tag: 'connected-component', + view: stache('rendered'), + ViewModel: class extends observe.Object { + connectedCallback(element) { + assert.equal(element.innerHTML, 'rendered', 'rendered view'); + assert.equal(element.nodeName, 'CONNECTED-COMPONENT', 'connectedCallback'); + return function () { + assert.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 () { + done(); + }); + }); + }); + } + }); +}); +/*can-dom-mutate@1.3.11#events/events*/ +define('can-dom-mutate@1.3.11#events/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-dom-mutate@1.3.11#dom-events*/ +define('can-dom-mutate@1.3.11#dom-events', [ + 'require', + 'exports', + 'module', + 'can-namespace', + './events/events' +], function (require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + var domMutateEvents = require('./events/events'); + module.exports = namespace.domMutateDomEvents = domMutateEvents; +}); +/*can-component@4.6.2#test/component-view-test*/ +define('can-component@4.6.2#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 (assert) { + 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; + assert.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; + assert.equal(hello.innerHTML.trim(), 'Hello', 'If no view is provided to Component, treat bindings as dynamic.'); + }); + QUnit.test('dynamic scoping', function (assert) { + 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; + assert.equal(hello.innerHTML.trim(), 'Hello Hello!'); + }); + QUnit.test('hello-world and whitespace around custom elements', function (assert) { + 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'); + assert.equal(helloWorld.innerHTML, 'Hello There!'); + }); + QUnit.test('self closing content tags', function (assert) { + Component.extend({ + 'tag': 'my-greeting', + view: stache('

      '), + viewModel: function () { + return new SimpleMap({ title: 'Component' }); + } + }); + var renderer = stache('{{site}} - {{title}}'); + var frag = renderer({ site: 'CanJS' }); + assert.equal(frag.firstChild.getElementsByTagName('span').length, 1, 'there is an h1'); + }); + QUnit.test('content extension stack overflow error', function (assert) { + 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(); + assert.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 (assert) { + 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); + var done = assert.async(); + var attempts = 0; + function checkCount() { + if (inserted >= 1 || attempts > 100) { + assert.equal(inited, 1, 'inited'); + assert.equal(inserted, 1, 'inserted'); + undo(); + done(); + } else { + attempts += 1; + setTimeout(checkCount, 30); + } + } + checkCount(); + }); + QUnit.test('Same component tag nested', function (assert) { + Component({ + 'tag': 'my-tag', + view: stache('

      ') + }); + var renderer = stache('
      OutterInner
      '); + var renderer2 = stache('
      3210
      '); + var renderer3 = stache('
      FirstSecond
      '); + assert.equal(renderer({}).firstChild.getElementsByTagName('p').length, 2, 'proper number of p tags'); + assert.equal(renderer2({}).firstChild.getElementsByTagName('p').length, 4, 'proper number of p tags'); + assert.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 (assert) { + 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({}); + assert.equal(innerHTML(frag.firstChild), '', 'child component is not inserted'); + canViewModel(frag.firstChild).attr('shown', true); + assert.equal(innerHTML(frag.firstChild.firstChild), 'Hello world.', 'child component is inserted'); + canViewModel(frag.firstChild).attr('shown', false); + assert.equal(innerHTML(frag.firstChild), '', 'child component is removed'); + }); + QUnit.test('references scopes are available to bindings nested in components (#2029)', function (assert) { + var renderer = stache('' + ''); + Component.extend({ tag: 'wrap-er' }); + Component.extend({ + tag: 'export-er', + events: { + 'init': function () { + var self = this.viewModel; + var done = assert.async(); + setTimeout(function () { + self.set('value', 100); + var wrapper = frag.lastChild, simpleExample = wrapper.firstChild, textNode = simpleExample.firstChild; + assert.equal(textNode.nodeValue, '100', 'updated value with reference'); + done(); + }, 100); + } + } + }); + Component.extend({ + tag: 'simple-example', + view: stache('{{key}}') + }); + var frag = renderer({}); + }); + QUnit.test(' (#2151)', function (assert) { + 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'); + assert.ok(innerHTML(lis[0]).indexOf('Item 1') >= 0, 'Item 1 written out'); + assert.ok(innerHTML(lis[1]).indexOf('Item 2') >= 0, 'Item 2 written out'); + }); + QUnit.test('two-way - reference - with tag', function (assert) { + 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(); + assert.equal(canViewModel(f1.firstChild.firstChild).get('name'), 'OTHER-EXPORT', 'viewModel set correctly'); + assert.equal(f1.firstChild.lastChild.nodeValue, 'OTHER-EXPORT', 'content'); + }); + runTestInOnlyDocument('custom renderer can provide setupBindings', function (assert) { + 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; + assert.equal(tn.nodeValue, 'qux', 'was bound!'); + }); + QUnit.test('view defaults to stache if set to a string', function (assert) { + 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; + assert.equal(hello.innerHTML.trim(), 'Hello World!'); + }); + QUnit.test('content tag available (#279)', function (assert) { + 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]; + assert.equal(span.innerHTML, 'CT-OUTER-LIGHT-DOM'); + }); + }); +}); +/*can-component@4.6.2#test/component-helpers-test*/ +define('can-component@4.6.2#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 (assert) { + assert.expect(2); + Component({ + tag: 'my-text', + view: stache('

      {{valueHelper()}}

      '), + helpers: { + valueHelper: function () { + return this.get('value'); + } + } + }); + var renderer = stache(''); + var frag = renderer({}); + assert.equal(frag.firstChild.firstChild.firstChild.nodeValue, 'value1'); + assert.equal(frag.lastChild.firstChild.firstChild.nodeValue, 'value2'); + }); + }); +}); +/*can-component@4.6.2#test/component-events-test*/ +define('can-component@4.6.2#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 () { + QUnit.test('value observables formerly (#550)', function (assert) { + 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'); + assert.equal(nameChanges, 2); + }); + QUnit.test('Component events bind to window', function (assert) { + window.tempMap = new SimpleMap(); + Component.extend({ + tag: 'window-events', + events: { + '{tempMap} prop': function () { + assert.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 (assert) { + assert.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 () { + assert.ok(true, 'called inserted once'); + } + } + }); + var renderer = stache(''); + domMutateNode.appendChild.call(this.fixture, renderer()); + var done = assert.async(); + setTimeout(function () { + undo(); + done(); + }, 100); + }); + QUnit.test('viewModel objects with Constructor functions as properties do not get converted (#1261)', function (assert) { + assert.expect(1); + var done = assert.async(); + 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 () { + assert.ok(true, 'Event got triggered'); + done(); + } + } + }); + var frag = stache('')(); + domMutateNode.appendChild.call(this.fixture, frag); + HANDLER.call(Test, { type: 'something' }); + }); + QUnit.test('removing bound viewModel properties on destroy #1415', function (assert) { + 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); + var done = assert.async(); + helpers.afterMutation(function () { + assert.ok(state.attr('product') == null, 'product was removed'); + done(); + }); + }); + QUnit.test('changing viewModel property rebinds {viewModel.<...>} events (#1529)', function (assert) { + assert.expect(2); + Component.extend({ + tag: 'rebind-viewmodel', + events: { + init: function () { + this.viewModel.set('anItem', new SimpleMap({})); + }, + '{scope.anItem} name': function () { + assert.ok(true, 'Change event on scope'); + }, + '{viewModel.anItem} name': function () { + assert.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 (assert) { + 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 + })); + var done = assert.async(); + helpers.runTasks([ + function () { + show.set(false); + }, + function () { + state.set('inner', null); + }, + function () { + assert.equal(removeCount, 1, 'internal removed once'); + show.set(true); + }, + function () { + state.set('inner', 2); + }, + function () { + state.set('inner', null); + }, + function () { + assert.equal(removeCount, 2, 'internal removed twice'); + undo(); + } + ], done); + }); + }); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-component@4.6.2#test/example-test*/ +define('can-component@4.6.2#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; + } + }); + QUnit.test('treecombo', function (assert) { + 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' + } + ] + } + ] + } + ]; + var done = assert.async(); + 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'); + }; + assert.equal(breadcrumbLIs().length, 1, 'Only the default title is shown'); + assert.equal(breadcrumbLIs()[0].innerHTML, 'Locations', 'The correct title from the attribute is shown'); + assert.equal(itemsList.length, optionsLis().length, 'first level items are displayed'); + domEvents.dispatch(optionsLis()[0], 'click'); + assert.equal(optionsLis()[0].className, 'active', 'toggling something not selected adds active'); + assert.ok(optionsLis()[0].getElementsByTagName('input')[0].checked, 'toggling something not selected checks checkbox'); + assert.equal(canViewModel(treecombo, 'selected').length, 1, 'there is one selected item'); + assert.equal(canViewModel(treecombo).selected[0], itemsList[0], 'the midwest is in selected'); + var selectedList = canViewModel(treecombo, 'selected'); + selectedList.pop(); + assert.equal(optionsLis()[0].className, '', 'removing selected item in viewModel removes \'active\' class'); + domEvents.dispatch(optionsLis()[0].getElementsByTagName('button')[0], 'click'); + assert.equal(breadcrumbLIs().length, 2, 'Only the default title is shown'); + assert.equal(breadcrumbLIs()[1].innerHTML, 'Midwest', 'The breadcrumb has an item in it'); + assert.ok(/Illinois/.test(optionsLis()[0].innerHTML), 'A child of the top breadcrumb is displayed'); + domEvents.dispatch(optionsLis()[0].getElementsByTagName('button')[0], 'click'); + assert.ok(/Chicago/.test(optionsLis()[0].innerHTML), 'A child of the top breadcrumb is displayed'); + assert.ok(!optionsLis()[0].getElementsByTagName('button').length, 'no show children button'); + domEvents.dispatch(breadcrumbLIs()[1], 'click'); + assert.equal(innerHTML(breadcrumbLIs()[1]), 'Midwest', 'The breadcrumb has an item in it'); + assert.ok(/Illinois/.test(innerHTML(optionsLis()[0])), 'A child of the top breadcrumb is displayed'); + domEvents.dispatch(breadcrumbLIs()[0], 'click'); + assert.equal(breadcrumbLIs().length, 1, 'Only the default title is shown'); + assert.equal(innerHTML(breadcrumbLIs()[0]), 'Locations', 'The correct title from the attribute is shown'); + done(); + }, 100); + }); + QUnit.test('deferred grid', function (assert) { + 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); + assert.equal(gridScope.get('waiting'), true, 'The grid is initially waiting on the deferreddata to resolve'); + var done = assert.async(); + var self = this; + var waitingHandler = function () { + gridScope.off('waiting', waitingHandler); + setTimeout(function () { + var tds = self.fixture.getElementsByTagName('td'); + assert.equal(tds.length, 2, 'there are 2 tds'); + gridScope.on('waiting', function (ev, newVal) { + if (newVal === false) { + setTimeout(function () { + tds = self.fixture.getElementsByTagName('td'); + assert.equal(innerHTML(tds[0]), 'Brian', 'td changed to brian'); + done(); + }, 100); + } + }); + viewModel.set = 1; + }, 100); + }; + gridScope.on('waiting', waitingHandler); + }); + QUnit.test('nextprev', function (assert) { + 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; + assert.ok(!/enabled/.test(prev.className), 'prev is not enabled'); + assert.ok(/enabled/.test(next.className), 'next is enabled'); + domEvents.dispatch(next, 'click'); + assert.ok(/enabled/.test(prev.getAttribute('class')), 'prev is enabled'); + }); + QUnit.test('page-count', function (assert) { + 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]; + assert.equal(span.firstChild.nodeValue, '1'); + paginator.next(); + assert.equal(span.firstChild.nodeValue, '2'); + paginator.next(); + assert.equal(span.firstChild.nodeValue, '3'); + }); + if (System.env !== 'canjs-test') { + QUnit.test('basic tabs', function (assert) { + 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; + var done = assert.async(); + helpers.runTasks([ + function () { + var lis = testArea.getElementsByTagName('li'); + assert.equal(lis.length, 3, 'three lis added'); + foodTypes.forEach(function (type, i) { + assert.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'); + assert.equal(lis.length, 4, 'li added'); + foodTypes.forEach(function (type, i) { + assert.equal(innerHTML(lis[i]), type.title, 'li ' + i + ' has the right content'); + }); + assert.equal(testArea.getElementsByTagName('panel').length, 4, 'panel added'); + canLog.log('SHIFTY'); + foodTypes.shift(); + }, + function () { + var lis = testArea.getElementsByTagName('li'); + assert.equal(lis.length, 3, 'removed li after shifting a foodType'); + foodTypes.forEach(function (type, i) { + assert.equal(innerHTML(lis[i]), type.title, 'li ' + i + ' has the right content'); + }); + var panels = testArea.getElementsByTagName('panel'); + assert.equal(lis[0].className, 'active', 'the first element is active'); + assert.equal(innerHTML(panels[0]), 'pasta, cereal', 'the first content is shown'); + assert.equal(innerHTML(panels[1]), '', 'the second content is removed'); + domEvents.dispatch(lis[1], 'click'); + lis = testArea.getElementsByTagName('li'); + assert.equal(lis[1].className, 'active', 'the second element is active'); + assert.equal(lis[0].className, '', 'the first element is not active'); + assert.equal(innerHTML(panels[0]), '', 'the second content is removed'); + assert.equal(innerHTML(panels[1]), 'ice cream, candy', 'the second content is shown'); + undo(); + } + ], done); + }); + } + }); +}); +/*can-component@4.6.2#test/component-slot-test*/ +define('can-component@4.6.2#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'); + QUnit.test(' Works', function (assert) { + 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(); + assert.equal(testView.firstChild.childNodes[0].nodeValue, 'Hello World'); + assert.equal(testView.firstChild.childNodes[1].nodeValue, 'Later Gator'); + }); + QUnit.test(' leakScope false acts as expected', function (assert) { + 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' + }); + assert.equal(testView.firstChild.childNodes[0].nodeValue, 'foo'); + assert.equal(testView.firstChild.childNodes[1].nodeValue, 'bar'); + }); + QUnit.test(' Re-use templates', function (assert) { + 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(); + assert.equal(testView.firstChild.childNodes[0].nodeValue, 'Hello World'); + assert.equal(testView.firstChild.childNodes[1].nodeValue, 'Hello World'); + }); + QUnit.test(' Works with default content', function (assert) { + var ViewModel = DefineMap.extend({}); + Component.extend({ + tag: 'my-email', + view: stache('' + 'Default Content' + ''), + ViewModel: ViewModel + }); + var renderer = stache('' + '' + ''); + var testView = renderer(); + assert.equal(testView.firstChild.innerHTML, 'Default Content'); + }); + QUnit.test(' Works in a self-closing template', function (assert) { + var ViewModel = DefineMap.extend({}); + Component.extend({ + tag: 'my-email', + view: stache('' + 'Default Content' + ''), + ViewModel: ViewModel + }); + var renderer = stache(''); + var testView = renderer(); + assert.equal(testView.firstChild.innerHTML, 'Default Content'); + }); + QUnit.test(' Context one-way binding works', function (assert) { + 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); + assert.equal(frag.firstChild.firstChild.innerHTML, 'Hello World'); + vm.subject = 'Later Gator'; + assert.equal(frag.firstChild.firstChild.innerHTML, 'Later Gator'); + }); + QUnit.test(' Context two-way binding works', function (assert) { + 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); + assert.equal(frag.firstChild.firstChild.innerHTML, 'Hello World'); + vm.subject = 'Later Gator'; + assert.equal(frag.firstChild.firstChild.innerHTML, 'Later Gator'); + childVM.subject = 'After a while crocodile'; + assert.equal(vm.subject, 'After a while crocodile'); + }); + QUnit.test(' Context child-to-parent binding works', function (assert) { + 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); + assert.equal(frag.firstChild.firstChild.innerHTML, 'Yo'); + childVM.subject = 'bar'; + assert.equal(frag.firstChild.firstChild.innerHTML, 'bar'); + assert.equal(vm.subject, 'bar'); + }); + QUnit.test(' Works alongside ', function (assert) { + 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(); + assert.equal(testView.firstChild.childNodes[0].firstChild.nodeValue, 'Hello World'); + assert.equal(testView.firstChild.childNodes[1].firstChild.nodeValue, 'Some content'); + }); + QUnit.test(' Works alongside with default content', function (assert) { + 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(); + assert.equal(testView.firstChild.childNodes[0].firstChild.nodeValue, 'Hello World'); + assert.equal(testView.firstChild.childNodes[1].nodeValue, 'Default content'); + }); + QUnit.test(' Can be used conditionally and will remove bindings', function (assert) { + 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(); + assert.equal(testView.firstChild.firstChild.firstChild.nodeValue, 'Hello World'); + var vm = viewModel(testView.firstChild); + vm.showSubject = false; + var done = assert.async(); + assert.equal(testView.firstChild.children.length, 0); + setTimeout(function () { + var handlers = vm[canSymbol.for('can.meta')].handlers; + assert.equal(handlers.get(['subject']).length, 0); + done(); + }, 50); + }); + QUnit.test('blocks directly nested within template', function (assert) { + 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'); + assert.equal(spans.length, 0, 'all spans removed'); + }); + QUnit.test('able to pass individual values (#291)', function (assert) { + 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'); + assert.equal(count.innerHTML, '10', 'updated count value'); + }); + QUnit.test('slots are passed as variables', function (assert) { + Component.extend({ + tag: 'pass-values-to-slots', + view: '', + ViewModel: { + count: { + type: 'number', + default: 0 + } + } + }); + var template = stache('' + '' + '{{count}}-{{this.count}}' + '' + ''); + var frag = template({ count: 1 }); + var passValuesToSlots = frag.firstElementChild || frag.firstChild; + var count = passValuesToSlots.querySelector('.count'); + assert.equal(count.innerHTML, '0-1', 'updated count value'); + }); +}); +/*can-global@1.0.1#can-global*/ +define('can-global@1.0.1#can-global', function (require, exports, module) { + (function (global, require, exports, module) { + var GLOBAL; + module.exports = function (setGlobal) { + if (setGlobal !== undefined) { + GLOBAL = setGlobal; + } + if (GLOBAL) { + return GLOBAL; + } else { + return GLOBAL = typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope ? self : typeof process === 'object' && {}.toString.call(process) === '[object process]' ? global : window; + } + }; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-test-helpers@1.1.4#lib/dev*/ +define('can-test-helpers@1.1.4#lib/dev', [ + 'require', + 'exports', + 'module', + 'can-log/dev/dev', + 'can-reflect', + 'can-global' +], function (require, exports, module) { + (function (global, require, exports, module) { + var dev = require('can-log/dev/dev'); + var canReflect = require('can-reflect'); + var GLOBAL = require('can-global'); + function makeExpectation(type) { + var original; + var expectedResults = []; + function stubbed() { + var message = canReflect.toArray(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) { + if (!global.test && global.QUnit) { + global.test = global.QUnit.test; + } + global.test.apply(null, arguments); + } + } + }; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-test-helpers@1.1.4#can-test-helpers*/ +define('can-test-helpers@1.1.4#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.6.2#test/component-define-test*/ +define('can-component@4.6.2#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 (assert) { + 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); + assert.ok(vm instanceof VM, 'Constructor was called'); + assert.equal(vm.firstName, 'Chris', 'ViewModel was set from scope'); + assert.equal(vm.lastName, 'Gomez', 'ViewModel was set from scope'); + assert.equal(frag.firstChild.innerHTML, 'Name: Chris Gomez', 'Rendered fullName'); + vm.firstName = 'Justin'; + vm.lastName = 'Meyer'; + assert.equal(frag.firstChild.innerHTML, 'Name: Justin Meyer', 'Rendered fullName after change'); + }); + QUnit.test('scope method works', function (assert) { + Component.extend({ + tag: 'my-element', + viewModel: function (properties, scope, element) { + assert.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 (assert) { + Component.extend({ + tag: 'test-element', + view: stache('{{someMethod()}}'), + ViewModel: { + someMethod: function () { + assert.ok(true, 'Function got called'); + return true; + } + } + }); + var renderer = stache(''); + renderer(); + }); + QUnit.test('helpers do not leak when leakscope is false (#77)', function (assert) { + 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(); + assert.equal(called, 0, 'Outer helper not called'); + }); + QUnit.test('helpers do leak when leakscope is true (#77)', function (assert) { + 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(); + assert.equal(called, 1, 'Outer helper called once'); + }); + if (System.env.indexOf('production') < 0) { + QUnit.test('warn if viewModel is assigned a DefineMap (#14)', function (assert) { + assert.expect(1); + var oldwarn = canDev.warn; + canDev.warn = function (mesg) { + assert.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 (assert) { + 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); + assert.ok(vm instanceof DefineMap, 'vm is a DefineMap'); + assert.equal(vm.firstName, 'Chris', 'ViewModel was set from scope'); + assert.equal(vm.lastName, 'Gomez', 'ViewModel was set from scope'); + assert.equal(frag.firstChild.innerHTML, 'Name: Chris Gomez', 'Rendered fullName'); + vm.firstName = 'Justin'; + vm.lastName = 'Meyer'; + assert.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 (assert) { + 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); + assert.ok(vm.items instanceof define.DefineList, 'vm is a DefineList'); + }); + testHelpers.dev.devOnlyTest('filename should be passed to stache() for inline views', function (assert) { + Component.extend({ + tag: 'my-filename-component', + ViewModel: {}, + view: '{{scope.filename}}' + }); + var renderer = stache(''); + var frag = renderer(); + assert.equal(frag.firstChild.innerHTML, 'MyFilenameComponentView', 'filename was provided to stache()'); + }); +}); +/*can-key@1.2.1#delete/delete*/ +define('can-key@1.2.1#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.1#replace-with/replace-with*/ +define('can-key@1.2.1#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.1#set/set*/ +define('can-key@1.2.1#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.1#walk/walk*/ +define('can-key@1.2.1#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.1#transform/transform*/ +define('can-key@1.2.1#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.1#can-key*/ +define('can-key@1.2.1#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.5.0#key/key*/ +define('can-simple-observable@2.5.0#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.1#can-value*/ +define('can-value@1.1.1#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.6.2#test/component-instantiation-test*/ +define('can-component@4.6.2#test/component-instantiation-test', [ + 'require', + 'exports', + 'module', + 'can-component', + 'can-define/map/map', + 'steal-qunit', + 'can-simple-map', + 'can-stache', + 'can-value', + 'can-globals' +], function (require, exports, module) { + (function (global, 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'); + var globals = require('can-globals'); + QUnit.module('can-component instantiation'); + QUnit.test('Components can be instantiated with new', function (assert) { + 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; + assert.ok(element, 'instance has element property'); + assert.equal(element.textContent, 'Hello ', 'element has correct text content'); + assert.ok(viewModel, 'instance has viewModel property'); + viewModel.message = 'world'; + assert.equal(element.textContent, 'Hello world', 'element has correct text content after updating viewModel'); + }); + QUnit.test('Components can be instantiated with - no scope', function (assert) { + 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; + assert.equal(element.innerHTML, 'Hello mundo', 'content is rendered'); + }); + QUnit.test('Components can be instantiated with - with plain content and scope', function (assert) { + 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; + assert.equal(element.innerHTML, 'Hello mundo', 'content is rendered'); + }); + QUnit.test('Components can be instantiated with - with scope - leakScope false', function (assert) { + 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; + assert.equal(element.innerHTML, 'Hello ', 'content is rendered with the provided scope'); + scopeVM.set('message', 'mundo'); + assert.equal(element.innerHTML, 'Hello mundo', 'content updates with the provided scope'); + }); + QUnit.test('Components can be instantiated with - with scope - leakScope true', function (assert) { + 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; + assert.equal(element.innerHTML, 'Hello world', 'content is rendered with the component\u2019s scope'); + }); + QUnit.test('Components can be instantiated with templates', function (assert) { + 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'); + assert.ok(inputElement, 'template rendered'); + assert.equal(inputElement.value, 'world', 'input has correct value'); + scopeVM.message = 'mundo'; + assert.equal(inputElement.value, 'mundo', 'input has correct value after updating scopeVM'); + }); + QUnit.test('Components can be instantiated with viewModel', function (assert) { + 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; + assert.equal(viewModel.fromChildProp, 'original from value', 'fromChildProp init'); + assert.equal(viewModel.plainProp, 'plain value', 'plainProp init'); + assert.equal(viewModel.toParentProp, undefined, 'toParentProp init'); + assert.equal(viewModel.twoWayProp, 'original bind value', 'twoWayProp init'); + assert.equal(viewModel.nullProp, null, 'nullProp init'); + fromMap.get('inner').set('key', 'new from value'); + assert.equal(viewModel.fromChildProp, 'new from value', 'viewModel updated after fromMap set'); + viewModel.toParentProp = 'new to value'; + assert.equal(toMap.get('inner').get('key'), 'new to value', 'toMap updated after viewModel set'); + bindMap.get('inner').set('key', 'new bind value'); + assert.equal(viewModel.twoWayProp, 'new bind value', 'viewModel updated after bindMap set'); + viewModel.twoWayProp = 'newest bind value'; + assert.equal(bindMap.get('inner').get('key'), 'newest bind value', 'bindMap updated after viewModel set'); + }); + QUnit.test('Components can be instantiated with all options', function (assert) { + 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; + assert.equal(element.innerHTML, 'Hello friend
      • eat
      ', 'element renders correctly'); + assert.equal(viewModel.items.length, 1, 'viewModel has items'); + viewModel.items.push('sleep'); + assert.equal(element.innerHTML, 'Hello friend
      • eat
      • sleep
      ', 'element updates correctly'); + }); + QUnit.test('Component binding instantiation works as documented', function (assert) { + 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; + assert.equal(viewModel.familyName, 'Flanders', 'component \u201Cbind\u201D prop is correct'); + assert.equal(viewModel.givenName, 'Milo', 'component \u201Cfrom\u201D prop is correct'); + assert.equal(viewModel.fullName, 'Milo Flanders', 'component \u201Cto\u201D prop is correct'); + var family = appVM.get('family'); + assert.equal(family.get('last'), 'Flanders', 'map \u201Cbind\u201D prop is correct'); + assert.equal(family.get('first'), 'Milo', 'map \u201Cfrom\u201D prop is correct'); + assert.equal(family.get('full'), 'Milo Flanders', 'map \u201Cto\u201D prop is correct'); + }); + QUnit.test('component instantiation is not observable', function (assert) { + 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'; + assert.equal(count, 1, 'only updated once'); + }); + QUnit.test('Can render in a document with no body', function (assert) { + var doc = document.implementation.createHTMLDocument('Testing'); + globals.setKeyValue('document', doc); + doc.documentElement.removeChild(doc.body); + var ComponentConstructor = Component.extend({ + tag: 'with-no-body', + view: 'test', + ViewModel: { + connectedCallback: function () { + } + } + }); + try { + new ComponentConstructor(); + assert.ok(true, 'rendered without throwing'); + } catch (e) { + assert.ok(false, 'threw' + e.toString()); + } finally { + globals.setKeyValue('document', document); + } + }); + QUnit.test('{initializeBindings: false} prevents setting up bindings until insert', function (assert) { + var ComponentConstructor = Component.extend({ + tag: 'some-random-tag', + view: '{{color}}', + ViewModel: { color: { default: 'red' } } + }); + var inst = new ComponentConstructor({ initializeBindings: false }); + assert.equal(inst.viewModel.color, undefined, 'ViewModel not yet setup'); + var view = stache('{{component}}'); + var frag = view({ component: inst }); + assert.equal(inst.viewModel.color, 'red', 'is red'); + assert.equal(frag.firstChild.firstChild.data, 'red', 'Now it is setup'); + }); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-component@4.6.2#test/component-in-stache-test*/ +define('can-component@4.6.2#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'); + var waitingCount = 0; + function finishOn2() { + waitingCount++; + if (waitingCount === 2) { + done(); + } + } + canReflect.onInstanceBoundChange(ComponentConstructor.ViewModel, function (instance, isBound) { + assert.equal(isBound, false, 'view model is no longer bound'); + finishOn2(); + }); + templateVM.set('showComponent', false); + assert.equal(fragment.textContent, '', 'fragment ends without content'); + finishOn2(); + }); + QUnit.test('Component can be removed from the page', function (assert) { + assert.expect(3); + var ToBeRemoved = Component.extend({ + tag: 'to-be-removed', + view: '{{prop}}', + ViewModel: { prop: 'string' }, + events: { + '{element} beforeremove': function () { + assert.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); + assert.ok(true, 'got here without an error'); + show.set(true); + prop.set(4); + assert.equal(frag.firstChild.getElementsByTagName('to-be-removed')[0].innerHTML, '4'); + }); + QUnit.test('Cleans up itself on the documentElement removal', function (assert) { + 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); + assert.ok(true, 'Called back without throwing'); + done(); + }); + var done = assert.async(); + doc.removeChild(doc.documentElement); + }); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-component@4.6.2#test/component-can-bind-test*/ +define('can-component@4.6.2#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.6.2#test/test*/ +define('can-component@4.6.2#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.8.0#test/test-define-only*/ +define('can-define@2.8.0#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', function (assert) { + assert.expect(5); + 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) { + assert.equal(oldVal, 'Mohamed Cherif'); + assert.equal(newVal, 'Justin Meyer'); + }); + assert.equal(p.fullName, 'Mohamed Cherif', 'fullName initialized right'); + p.bind('first', function (el, newVal, oldVal) { + assert.equal(newVal, 'Justin', 'first new value'); + assert.equal(oldVal, 'Mohamed', 'first old value'); + }); + queues.batch.start(); + p.first = 'Justin'; + p.last = 'Meyer'; + queues.batch.stop(); + }); + QUnit.test('basics set', function (assert) { + assert.expect(2); + var Defined = function (prop) { + this.prop = prop; + }; + define(Defined.prototype, { + prop: { + set: function (newVal) { + return 'foo' + newVal; + } + } + }); + var def = new Defined(); + def.prop = 'bar'; + assert.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'; + assert.equal(defCallback.prop, 'foobar', 'setter callback works'); + }); + QUnit.test('basic Type', function (assert) { + 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'); + assert.equal(t.foo.getName(), 'Justin', 'correctly created an instance'); + var brian = new Foo('brian'); + t.foo = brian; + assert.equal(t.foo, brian, 'same instances'); + }); + QUnit.test('type converters', function (assert) { + 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); + assert.ok(t.date instanceof Date, 'converted to date'); + assert.equal(t.string, '5', 'converted to string'); + assert.equal(t.number, 5, 'converted to number'); + assert.equal(t.bool, false, 'converted to boolean'); + assert.equal(t.htmlbool, true, 'converted to htmlbool'); + assert.equal(t.leaveAlone, obj, 'left as object'); + t.number = '15'; + assert.ok(t.number === 15, 'converted to number'); + }); + QUnit.test('basics value', function (assert) { + var Typer = function (prop) { + if (prop !== undefined) { + this.prop = prop; + } + }; + define(Typer.prototype, { prop: { default: 'foo' } }); + var t = new Typer(); + assert.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(); + assert.ok(t1.prop !== t2.prop, 'different array instances'); + assert.ok(Array.isArray(t1.prop), 'its an array'); + }); + QUnit.test('basics Value', function (assert) { + var Typer = function (prop) { + }; + define(Typer.prototype, { + prop: { + Default: Array, + type: '*' + } + }); + var t1 = new Typer(), t2 = new Typer(); + assert.ok(t1.prop !== t2.prop, 'different array instances'); + assert.ok(Array.isArray(t1.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 (assert) { + var Typer = function (prop) { + }; + define(Typer.prototype, { + prop: { + set: function () { + this.foo = 'bar'; + } + }, + foo: '*' + }); + var t = new Typer(); + t.prop = false; + assert.deepEqual({ + foo: t.foo, + prop: t.prop + }, { + foo: 'bar', + prop: false + }, 'got the right props'); + }); + QUnit.test('type happens before the set', function (assert) { + assert.expect(2); + var Typer = function () { + }; + define(Typer.prototype, { + prop: { + type: 'number', + set: function (newValue) { + assert.equal(typeof newValue, 'number', 'got a number'); + return newValue + 1; + } + } + }); + var map = new Typer(); + map.prop = '5'; + assert.equal(map.prop, 6, 'number'); + }); + QUnit.test('getter and setter work', function (assert) { + assert.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 + }); + assert.equal(p.page, 3, 'page get right'); + p.bind('page', function (ev, newValue, oldValue) { + assert.equal(newValue, 2, 'got new value event'); + assert.equal(oldValue, 3, 'got old value event'); + }); + p.page = 2; + assert.equal(p.page, 2, 'page set right'); + assert.equal(p.offset, 10, 'page offset set'); + }); + QUnit.test('getter with initial value', function (assert) { + 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(); + assert.equal(g.vals.length, 0, 'zero items in array'); + }); + QUnit.test('default behaviors with "*" work for attributes', function (assert) { + assert.expect(6); + var DefaultMap = define.Constructor({ + '*': { + type: 'number', + set: function (newVal) { + assert.ok(true, 'set called'); + return newVal; + } + }, + someNumber: { default: '5' }, + number: {} + }); + var map = new DefaultMap(); + assert.equal(map.someNumber, '5', 'default values are not type converted anymore'); + map.someNumber = '5'; + assert.equal(map.someNumber, 5, 'on a set, they should be type converted'); + map.number = '10'; + assert.equal(map.number, 10, 'value of number should be converted to a number'); + }); + QUnit.test('nested define', function (assert) { + 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(); + assert.equal(nested.test.name, nailedIt); + assert.equal(nested.examples.one.name, nailedIt); + assert.equal(nested.examples.two.deep.name, nailedIt); + assert.ok(nested.test instanceof Example); + assert.ok(nested.examples.one instanceof Example); + assert.ok(nested.examples.two.deep instanceof Example); + }); + QUnit.test('Can make an attr alias a compute (#1470)', function (assert) { + assert.expect(9); + 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; + assert.equal(getMap.value, 1, 'initial value read from compute'); + var bindCallbacks = 0; + getMap.bind('value', function (ev, newVal, oldVal) { + switch (bindCallbacks) { + case 0: + assert.equal(newVal, 2, '0 - bind called with new val'); + assert.equal(oldVal, 1, '0 - bind called with old val'); + break; + case 1: + assert.equal(newVal, 3, '1 - bind called with new val'); + assert.equal(oldVal, 2, '1 - bind called with old val'); + break; + case 2: + assert.equal(newVal, 4, '2 - bind called with new val'); + assert.equal(oldVal, 3, '2 - bind called with old val'); + break; + } + bindCallbacks++; + }); + computeValue.set(2); + getMap.value = 3; + assert.equal(getMap.value, 3, 'read value is 3'); + assert.equal(computeValue.get(), 3, 'the compute value is 3'); + var newComputeValue = new SimpleObservable(4); + getMap.value = newComputeValue; + }); + QUnit.test('One event on getters (#1585)', function (assert) { + 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++; + }); + assert.equal(appState.person, null, 'no personId and no lastSetValue'); + appState.personId = 5; + assert.equal(appState.person.name, 'Jose', 'a personId, providing Jose'); + assert.ok(appState.person instanceof Person, 'got a person instance'); + appState.person = { name: 'Julia' }; + assert.ok(appState.person instanceof Person, 'got a person instance'); + assert.equal(personEvents, 2); + }); + QUnit.test('Can read a defined property with a set/get method (#1648)', function (assert) { + var Map = define.Constructor({ + foo: { + default: '', + set: function (setVal) { + return setVal; + }, + get: function (lastSetVal) { + return lastSetVal; + } + } + }); + var map = new Map(); + assert.equal(map.foo, '', 'Calling .foo returned the correct value'); + map.foo = 'baz'; + assert.equal(map.foo, 'baz', 'Calling .foo returned the correct value'); + }); + QUnit.test('Can bind to a defined property with a set/get method (#1648)', function (assert) { + assert.expect(3); + var Map = define.Constructor({ + foo: { + default: '', + set: function (setVal) { + return setVal; + }, + get: function (lastSetVal) { + return lastSetVal; + } + } + }); + var map = new Map(); + map.bind('foo', function () { + assert.ok(true, 'Bound function is called'); + }); + assert.equal(map.foo, '', 'Calling .attr(\'foo\') returned the correct value'); + map.foo = 'baz'; + assert.equal(map.foo, 'baz', 'Calling .attr(\'foo\') returned the correct value'); + }); + QUnit.test('type converters handle null and undefined in expected ways (1693)', function (assert) { + 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 + }); + assert.equal(t.date, undefined, 'converted to date'); + assert.equal(t.string, undefined, 'converted to string'); + assert.equal(t.number, undefined, 'converted to number'); + assert.equal(t.boolean, undefined, 'converted to boolean'); + assert.equal(t.htmlbool, false, 'converted to htmlbool'); + assert.equal(t.leaveAlone, undefined, 'left as object'); + t = new Typer({ + date: null, + string: null, + number: null, + 'boolean': null, + htmlbool: null, + leaveAlone: null + }); + assert.equal(t.date, null, 'converted to date'); + assert.equal(t.string, null, 'converted to string'); + assert.equal(t.number, null, 'converted to number'); + assert.equal(t.boolean, null, 'converted to boolean'); + assert.equal(t.htmlbool, false, 'converted to htmlbool'); + assert.equal(t.leaveAlone, null, 'left as object'); + }); + QUnit.test('Initial value does not call getter', function (assert) { + assert.expect(0); + var Map = define.Constructor({ + count: { + get: function (lastVal) { + assert.ok(false, 'Should not be called'); + return lastVal; + } + } + }); + new Map({ count: 100 }); + }); + QUnit.test('getters produce change events', function (assert) { + var Map = define.Constructor({ + count: { + get: function (lastVal) { + return lastVal; + } + } + }); + var map = new Map(); + map.bind('count', function () { + assert.ok(true, 'change called'); + }); + map.count = 22; + }); + QUnit.test('Asynchronous virtual properties cause extra recomputes (#1915)', function (assert) { + var done = assert.async(); + 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) { + assert.ok(false, 'Getter ran twice'); + } + ran = true; + return foo * 2; + } + } + } + }); + var vm = new VM(); + vm.bind('bar', function () { + }); + setTimeout(function () { + assert.equal(vm.bar, 10); + done(); + }, 200); + }); + QUnit.test('Default values cannot be set (#8)', function (assert) { + 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(); + assert.equal(p.fullName, 'Chris Gomez', 'Fullname is correct'); + p.first = 'Sara'; + assert.equal(p.fullName, 'Sara Gomez', 'Fullname is correct after update'); + }); + QUnit.test('default type is setable', function (assert) { + var Person = function () { + }; + define(Person.prototype, { + '*': 'string', + first: { default: 1 }, + last: { default: 2 } + }); + var p = new Person(); + assert.ok(p.first === '1', typeof p.first); + assert.ok(p.last === '2', typeof p.last); + }); + QUnit.test('expandos are added in define.setup (#25)', function (assert) { + var MyMap = define.Constructor({}); + var map = new MyMap({ prop: 4 }); + map.on('prop', function () { + assert.ok(true, 'prop event called'); + }); + map.prop = 5; + }); + QUnit.test('Set property with type compute', function (assert) { + var MyMap = define.Constructor({ computeProp: { type: 'compute' } }); + var m = new MyMap(); + m.computeProp = new SimpleObservable(0); + assert.equal(m.computeProp, 0, 'Property has correct value'); + m.computeProp = new SimpleObservable(1); + assert.equal(m.computeProp, 1, 'Property has correct value'); + }); + QUnit.test('Compute type property can have a default value', function (assert) { + var MyMap = define.Constructor({ + computeProp: { + type: 'compute', + default: function () { + return 0; + } + } + }); + var m = new MyMap(); + assert.equal(m.computeProp, 0, 'Property has correct value'); + m.computeProp = 1; + assert.equal(m.computeProp, 1, 'Property has correct value'); + }); + QUnit.test('Compute type property with compute default value triggers change events when updated', function (assert) { + 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) { + assert.equal(newVal, expected, 'Compute fired change event'); + }); + m.on('computeProp', function (ev, newVal) { + assert.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 (assert) { + var c = new SimpleObservable(0); + var MyMap = define.Constructor({ + computeProp: { + type: 'compute', + default: function () { + return c; + } + } + }); + var m = new MyMap(); + assert.equal(m.computeProp, 0, 'Property has correct value'); + c.set(1); + assert.equal(m.computeProp, 1, 'Property has correct value'); + }); + QUnit.test('Extensions can modify definitions', function (assert) { + 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(); + assert.equal(map.foo, 'extended', 'Value was set via extension'); + assert.equal(map.bar, 'defined', 'Value was set via definition'); + define.extensions = oldExtensions; + }); + QUnit.test('Properties are enumerable', function (assert) { + assert.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]; + } + assert.deepEqual(copy, { + foo: 'bar', + baz: 'qux' + }); + }); + QUnit.test('Doesn\'t override canSymbol.iterator if already on the prototype', function (assert) { + 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) { + assert.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 (assert) { + 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) { + assert.equal(oldVal, 'Mohamed Cherif'); + assert.equal(newVal, 'Justin Meyer'); + }); + assert.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 (assert) { + 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) { + assert.equal(oldVal, 'Mohamed Cherif'); + assert.equal(newVal, 'Justin Meyer'); + }); + assert.equal(p.fullName, 'Mohamed Cherif', 'fullName initialized right'); + p.fullName = 'Justin Meyer'; + }); + QUnit.test('set and value work together (#87)', function (assert) { + var Type = define.Constructor({ + prop: { + default: 2, + set: function (num) { + return num * num; + } + } + }); + var instance = new Type(); + assert.equal(instance.prop, 4, 'used setter'); + }); + QUnit.test('async setter is provided', function (assert) { + assert.expect(5); + 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(); + assert.equal(instance.prop, 4, 'used async setter'); + assert.equal(instance.prop2, undefined, 'used async setter'); + instance.on('prop2', function (ev, newVal, oldVal) { + assert.equal(newVal, 9, 'updated'); + assert.equal(oldVal, undefined, 'updated'); + }); + RESOLVE(9); + assert.equal(instance.prop2, 9, 'used async setter updates after'); + }); + QUnit.test('setter with default value causes an infinite loop (#142)', function (assert) { + var A = define.Constructor({ + val: { + default: 'hello', + set: function (val) { + if (this.val) { + } + return val; + } + } + }); + var a = new A(); + assert.equal(a.val, 'hello', 'creating an instance should not cause an inifinte loop'); + }); + QUnit.test('defined properties are configurable', function (assert) { + 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(); + assert.equal(a.val, 'bar', 'It was redefined'); + }); + testHelpers.dev.devOnlyTest('warn on using a Constructor for small-t type definitions', function (assert) { + assert.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({}); + } + } + }); + assert.equal(finishErrorCheck(), 1); + }); + testHelpers.dev.devOnlyTest('warn with constructor for Value instead of Default (#340)', function (assert) { + assert.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 } }); + assert.equal(finishErrorCheck(), 1); + }); + QUnit.test('canReflect.onKeyValue (#363)', function (assert) { + 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) { + assert.equal(newVal, 'bye'); + assert.equal(oldVal, 'Hello'); + }); + greeting.message = 'bye'; + }); + QUnit.test('value lastSet has default value (#397)', function (assert) { + var Defaulted = function () { + }; + define(Defaulted.prototype, { + hasDefault: { + default: 42, + value: function hasDefaultValue(props) { + assert.equal(props.lastSet.get(), 42, 'props.lastSet works'); + props.resolve(props.lastSet.get()); + } + } + }); + var defaulted = new Defaulted(); + assert.equal(defaulted.hasDefault, 42, 'hasDefault value.lastSet set default value'); + }); + QUnit.test('binding computed properties do not observation recordings (#406)', function (assert) { + 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(); + assert.equal(records.valueDependencies.size, 0, 'nothing recorded'); + }); + testHelpers.dev.devOnlyTest('warning when setting during a get', function (assert) { + var Type = function Type() { + }; + var msg = /.* This can cause infinite loops and performance issues.*/; + var teardownWarn = testHelpers.dev.willWarn(msg, function (text, match) { + if (match) { + assert.ok(true, 'warning fired'); + } + }); + define(Type.prototype, { + prop: { + get: function () { + if (!this.prop2) { + this.prop2 = 'baz'; + } + return ''; + } + }, + prop2: 'string' + }); + var inst = new Type(); + inst.on('prop', function () { + }); + inst.prop2 = ''; + assert.equal(teardownWarn(), 1, 'warning correctly generated'); + teardownWarn = testHelpers.dev.willWarn(msg, function (text, match) { + if (match) { + assert.ok(false, 'warning incorrectly fired'); + } + }); + inst.prop2 = 'quux'; + teardownWarn(); + }); + testHelpers.dev.devOnlyTest('warning when setting during a get (batched)', function (assert) { + var msg = /.* This can cause infinite loops and performance issues.*/; + var Type = function Type() { + }; + var teardownWarn = testHelpers.dev.willWarn(msg, function (text, match) { + if (match) { + assert.ok(true, 'warning fired'); + } + }); + define(Type.prototype, { + prop: { + get: function () { + if (!this.prop2) { + this.prop2 = 'baz'; + return ''; + } + } + }, + prop2: 'string' + }); + var inst = new Type(); + queues.batch.start(); + inst.on('prop', function () { + }); + inst.prop2 = ''; + queues.batch.stop(); + assert.equal(teardownWarn(), 1, 'warning correctly generated'); + teardownWarn = testHelpers.dev.willWarn(msg, function (text, match) { + if (match) { + assert.ok(false, 'warning incorrectly fired'); + } + }); + queues.batch.start(); + inst.prop2 = 'quux'; + queues.batch.stop(); + teardownWarn(); + }); + testHelpers.dev.devOnlyTest('warning when setting during a get (setter)', function (assert) { + var msg = /.* This can cause infinite loops and performance issues.*/; + var Type = function Type() { + }; + var teardownWarn = testHelpers.dev.willWarn(msg, function (text, match) { + if (match) { + assert.ok(true, 'warning fired'); + } + }); + var cell; + define(Type.prototype, { + prop: { + get: function () { + if (!this.prop2) { + this.prop2 = 'baz'; + } + return cell; + }, + set: function (val) { + cell = val; + } + }, + prop2: 'string' + }); + var inst = new Type(); + inst.on('prop', function () { + }); + inst.prop2 = ''; + assert.equal(teardownWarn(), 1, 'warning correctly generated'); + teardownWarn = testHelpers.dev.willWarn(msg, function (text, match) { + if (match) { + assert.ok(false, 'warning incorrectly fired'); + } + }); + inst.prop2 = 'quux'; + teardownWarn(); + }); + testHelpers.dev.devOnlyTest('warnings are given when type or default is ignored', function (assert) { + var testCases = [ + { + name: 'zero-arg getter, no setter when property is set', + definition: { + get: function () { + return 'whatever'; + } + }, + warning: /Set value for property .* ignored/, + setProp: true, + expectedWarnings: 1 + }, + { + name: 'type with zero-arg getter, no setter', + definition: { + type: String, + get: function () { + return 'whatever'; + } + }, + warning: /type value for property .* ignored/, + setProp: false, + expectedWarnings: 1 + }, + { + name: 'Type with zero-arg getter, no setter', + definition: { + Type: {}, + get: function () { + return 'whatever'; + } + }, + warning: /Type value for property .* ignored/, + setProp: false, + expectedWarnings: 1 + }, + { + name: 'only default type with zero-arg getter, no setter - should not warn', + definition: { + get: function () { + return 'whatever'; + } + }, + warning: /type value for property .* ignored/, + setProp: false, + expectedWarnings: 0 + }, + { + name: 'type with zero-arg getter, with setter - should not warn', + definition: { + type: String, + get: function () { + return 'whatever'; + }, + set: function (val) { + return val; + } + }, + warning: /type value for property .* ignored/, + setProp: false, + expectedWarnings: 0 + }, + { + name: 'Type with zero-arg getter, with setter - should not warn', + definition: { + Type: {}, + get: function () { + return 'whatever'; + }, + set: function (val) { + return val; + } + }, + warning: /Type value for property .* ignored/, + setProp: false, + expectedWarnings: 0 + }, + { + name: 'default with zero-arg getter, no setter', + definition: { + default: 'some thing', + get: function () { + return 'whatever'; + } + }, + warning: /default value for property .* ignored/, + setProp: false, + expectedWarnings: 1 + }, + { + name: 'Default with zero-arg getter, no setter', + definition: { + Default: function () { + }, + get: function () { + return 'whatever'; + } + }, + warning: /Default value for property .* ignored/, + setProp: false, + expectedWarnings: 1 + }, + { + name: 'default with zero-arg getter, with setter - should not warn', + definition: { + default: 'some thing', + get: function () { + return 'whatever'; + }, + set: function (val) { + return val; + } + }, + warning: /default value for property .* ignored/, + setProp: false, + expectedWarnings: 0 + }, + { + name: 'Default with zero-arg getter, with setter - should not warn', + definition: { + Default: function () { + }, + get: function () { + return 'whatever'; + }, + set: function (val) { + return val; + } + }, + warning: /Default value for property .* ignored/, + setProp: false, + expectedWarnings: 0 + } + ]; + testCases.forEach(function (testCase) { + var VM = function () { + }; + var warnCount = testHelpers.dev.willWarn(testCase.warning); + define(VM.prototype, { + derivedProp: testCase.definition, + '*': { type: define.types.observable } + }); + var vm = new VM(); + canReflect.onKeyValue(vm, 'derivedProp', function () { + }); + if (testCase.setProp) { + vm.derivedProp = 'smashed it!'; + } + assert.equal(warnCount(), testCase.expectedWarnings, 'got correct number of warnings for ' + testCase.name); + }); + }); +}); +/*can-define@2.8.0#list/list-test*/ +define('can-define@2.8.0#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 (assert) { + var list = new DefineList([ + 'a', + 'b', + 'c' + ]); + list.on('add', function (ev, newVals, index) { + assert.deepEqual(newVals, ['d']); + assert.equal(index, 3); + }); + list.push('d'); + }); + QUnit.test('list attr changes length', function (assert) { + var l = new DefineList([ + 0, + 1, + 2 + ]); + l.set(3, 3); + assert.equal(l.length, 4); + }); + QUnit.test('remove on pop', function (assert) { + var l = new DefineList([ + 0, + 1, + 2 + ]); + l.pop(); + assert.equal(l.length, 2); + assert.deepEqual(l.get(), [ + 0, + 1 + ]); + }); + QUnit.test('list splice', function (assert) { + var l = new DefineList([ + 0, + 1, + 2, + 3 + ]); + l.on('add', function (ev, newVals, index) { + assert.deepEqual(newVals, [ + 'a', + 'b' + ], 'got the right newVals'); + assert.equal(index, 1, 'adding items'); + }); + l.on('remove', function (ev, oldVals, index) { + assert.deepEqual(oldVals, [ + 1, + 2 + ], 'got the right oldVals'); + assert.equal(index, 1, 'no new Vals'); + }); + l.splice(1, 2, 'a', 'b'); + assert.deepEqual(l.get(), [ + 0, + 'a', + 'b', + 3 + ], 'serialized'); + }); + QUnit.test('Array accessor methods', function (assert) { + assert.expect(11); + var l = new DefineList([ + 'a', + 'b', + 'c' + ]), sliced = l.slice(2), joined = l.join(' | '), concatenated = l.concat([ + 2, + 1 + ], new DefineList([0])); + assert.ok(sliced instanceof DefineList, 'Slice is an Observable list'); + assert.equal(sliced.length, 1, 'Sliced off two elements'); + assert.equal(sliced[0], 'c', 'Single element as expected'); + assert.equal(joined, 'a | b | c', 'Joined list properly'); + assert.ok(concatenated instanceof DefineList, 'Concatenated is an Observable list'); + assert.deepEqual(concatenated.serialize(), [ + 'a', + 'b', + 'c', + 2, + 1, + 0 + ], 'DefineList concatenated properly'); + l.forEach(function (letter, index) { + assert.ok(true, 'Iteration'); + if (index === 0) { + assert.equal(letter, 'a', 'First letter right'); + } + if (index === 2) { + assert.equal(letter, 'c', 'Last letter right'); + } + }); + }); + QUnit.test('Concatenated list items Equal original', function (assert) { + var l = new DefineList([ + { firstProp: 'Some data' }, + { secondProp: 'Next data' } + ]), concatenated = l.concat([ + { hello: 'World' }, + { foo: 'Bar' } + ]); + assert.ok(l[0] === concatenated[0], 'They are Equal'); + assert.ok(l[1] === concatenated[1], 'They are Equal'); + }); + QUnit.test('Lists with maps concatenate properly', function (assert) { + 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); + assert.ok(people.length === 8, 'List length is right'); + assert.ok(people[0] === me, 'Map in list === vars created before concat'); + assert.ok(people[1] instanceof Person, 'Animal got serialized to Person'); + }); + QUnit.test('splice removes items in IE (#562)', function (assert) { + var l = new DefineList(['a']); + l.splice(0, 1); + assert.ok(!l.get(0), 'all props are removed'); + }); + QUnit.test('reverse triggers add/remove events (#851)', function (assert) { + assert.expect(4); + var l = new DefineList([ + 1, + 2, + 3 + ]); + l.on('add', function () { + assert.ok(true, 'add called'); + }); + l.on('remove', function () { + assert.ok(true, 'remove called'); + }); + l.on('length', function () { + assert.ok(true, 'length should be called'); + }); + l.reverse(); + assert.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'); + }); + QUnit.test('No Add Events if DefineList Splice adds the same items that it is removing. (#1277, #1399)', function (assert) { + var list = new DefineList([ + 'a', + 'b' + ]); + list.bind('add', function () { + assert.ok(false, 'Add callback should not be called.'); + }); + list.bind('remove', function () { + assert.ok(false, 'Remove callback should not be called.'); + }); + var result = list.splice(0, 2, 'a', 'b'); + assert.deepEqual(result, [ + 'a', + 'b' + ]); + }); + QUnit.test('add event always returns an array as the value (#998)', function (assert) { + var list = new DefineList([]), msg; + list.bind('add', function (ev, newElements, index) { + assert.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]); + }); + QUnit.test('Setting with .set() out of bounds of length triggers add event with leading undefineds', function (assert) { + var list = new DefineList([1]); + list.bind('add', function (ev, newElements, index) { + assert.deepEqual(newElements, [ + undefined, + undefined, + 4 + ], 'Leading undefineds are included'); + assert.equal(index, 1, 'Index takes into account the leading undefineds from a .set()'); + }); + list.set(3, 4); + }); + QUnit.test('No events should fire if removals happened on empty arrays', function (assert) { + var list = new DefineList([]), msg; + list.bind('remove', function (ev, removed, index) { + assert.ok(false, msg); + }); + msg = 'works on pop'; + list.pop(); + msg = 'works on shift'; + list.shift(); + assert.ok(true, 'No events were fired.'); + }); + QUnit.test('setting an index out of bounds does not create an array', function (assert) { + assert.expect(1); + var l = new DefineList(); + l.set('1', 'foo'); + assert.equal(l.get('1'), 'foo'); + }); + QUnit.test('splice with similar but less items works (#1606)', function (assert) { + var list = new DefineList([ + 'aa', + 'bb', + 'cc' + ]); + list.splice(0, list.length, 'aa', 'cc', 'dd'); + assert.deepEqual(list.get(), [ + 'aa', + 'cc', + 'dd' + ]); + list.splice(0, list.length, 'aa', 'cc'); + assert.deepEqual(list.get(), [ + 'aa', + 'cc' + ]); + }); + QUnit.test('filter returns same list type (#1744)', function (assert) { + var ParentList = DefineList.extend(); + var ChildList = ParentList.extend(); + var children = new ChildList([ + 1, + 2, + 3 + ]); + assert.ok(children.filter(function () { + }) instanceof ChildList); + }); + QUnit.test('reverse returns the same list instance (#1744)', function (assert) { + var ParentList = DefineList.extend(); + var ChildList = ParentList.extend(); + var children = new ChildList([ + 1, + 2, + 3 + ]); + assert.ok(children.reverse() === children); + }); + QUnit.test('slice and join are observable by a compute (#1884)', function (assert) { + assert.expect(2); + var list = new DefineList([ + 1, + 2, + 3 + ]); + var sliced = new Observation(function () { + return list.slice(0, 1); + }); + canReflect.onValue(sliced, function (newVal) { + assert.deepEqual(newVal.get(), [2], 'got a new DefineList'); + }); + var joined = new Observation(function () { + return list.join(','); + }); + canReflect.onValue(joined, function (newVal) { + assert.equal(newVal, '2,3', 'joined is observable'); + }); + list.shift(); + }); + QUnit.test('list.replace', function (assert) { + 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); + assert.equal(myList.length, 3); + assert.equal(myList[0].name, 'Aubree'); + assert.equal(myList[1].name, 'Leah'); + assert.equal(myList[2].name, 'Lily', 'Can replace a List with an Array.'); + myList.replace(firstArray); + assert.equal(myList.length, 3); + assert.equal(myList[0].name, 'Marshall'); + assert.equal(myList[1].name, 'Austin'); + assert.equal(myList[2].name, 'Hyrum', 'Can replace a List with another List.'); + }); + QUnit.test('list.map', function (assert) { + 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; + }); + assert.equal(newList.length, 3); + assert.equal(newList[0].name, 'Marshall'); + assert.equal(newList[0].lastName, 'Thompson'); + assert.equal(newList[1].name, 'Austin'); + assert.equal(newList[1].lastName, 'Thompson'); + assert.equal(newList[2].name, 'Hyrum'); + assert.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) { + assert.ok(err.message.match(/testMe/), 'Does not return the same type of list.'); + } + }); + QUnit.test('list.sort a simple list', function (assert) { + var myList = new DefineList([ + 'Marshall', + 'Austin', + 'Hyrum' + ]); + myList.sort(); + assert.equal(myList.length, 3); + assert.equal(myList[0], 'Austin'); + assert.equal(myList[1], 'Hyrum'); + assert.equal(myList[2], 'Marshall', 'Basic list was properly sorted.'); + }); + QUnit.test('list.sort a list of objects', function (assert) { + 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; + } + }); + assert.equal(objList.length, 3); + assert.equal(objList[0].name, 'Austin'); + assert.equal(objList[1].name, 'Hyrum'); + assert.equal(objList[2].name, 'Marshall', 'List of objects was properly sorted.'); + }); + QUnit.test('list.sort a list of objects without losing reference (#137)', function (assert) { + 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; + }); + assert.equal(unSorted[0], sorted[2], 'items should be equal'); + }); + QUnit.test('list defines', function (assert) { + assert.expect(6); + 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 } + ]); + assert.ok(todos.item(0) instanceof Todo, 'correct instance'); + assert.equal(todos.completed.length, 1, 'only one todo'); + todos.on('completed', function (ev, newVal, oldVal) { + assert.ok(newVal instanceof TodoList, 'right type'); + assert.equal(newVal.length, 2, 'all items'); + assert.ok(oldVal instanceof TodoList, 'right type'); + assert.equal(oldVal.length, 1, 'all items'); + }); + todos.setCompletedTo(true); + }); + QUnit.test('extending the base supports overwriting _eventSetup', function (assert) { + var L = DefineList.extend({}); + Object.getOwnPropertyDescriptor(DefineMap.prototype, '_eventSetup'); + L.prototype.arbitraryProp = true; + assert.ok(true, 'set arbitraryProp'); + L.prototype._eventSetup = function () { + }; + assert.ok(true, 'worked'); + }); + QUnit.test('setting expandos on a DefineList', function (assert) { + var DL = DefineList.extend({ count: 'number' }); + var dl = new DL(); + dl.assign({ + count: 5, + skip: 2 + }); + assert.equal(dl.get('count'), 5, 'read with .get defined'); + assert.equal(dl.count, 5, 'read with . defined'); + assert.equal(dl.get('skip'), 2, 'read with .get expando'); + assert.equal(dl.skip, 2, 'read with . expando'); + assert.equal(dl.get('limit'), undefined, 'read with .get undefined'); + }); + QUnit.test('passing a DefineList to DefineList (#33)', function (assert) { + var m = new DefineList([ + {}, + {} + ]); + var m2 = new DefineList(m); + assert.deepEqual(m.get(), m2.get()); + assert.ok(m[0] === m2[0], 'index the same'); + assert.ok(m[1] === m2[1], 'index the same'); + }); + QUnit.test('reading and setting expandos', function (assert) { + var list = new DefineList(); + var countObservation = new Observation(function () { + return list.get('count'); + }, null, function (newValue) { + assert.equal(newValue, 1000, 'got new value'); + }); + countObservation.start(); + list.set('count', 1000); + assert.equal(countObservation.value, 1000); + var list2 = new DefineList(); + list2.on('count', function (ev, newVal) { + assert.equal(newVal, 5); + }); + list2.set('count', 5); + }); + QUnit.test('extending DefineList constructor functions (#61)', function (assert) { + 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) { + assert.equal(newVal, 'PROP'); + assert.equal(oldVal, undefined); + }); + list.on('bProp', function (ev, newVal, oldVal) { + assert.equal(newVal, 'FOO'); + assert.equal(oldVal, undefined); + }); + list.on('cProp', function (ev, newVal, oldVal) { + assert.equal(newVal, 'BAR'); + assert.equal(oldVal, undefined); + }); + list.aProp = 'PROP'; + list.bProp = 'FOO'; + list.cProp = 'BAR'; + assert.ok(list.aMethod); + assert.ok(list.bMethod); + assert.ok(list.cMethod); + }); + QUnit.test('extending DefineList constructor functions more than once (#61)', function (assert) { + 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) { + assert.equal(newVal, 'PROP', 'aProp newVal on list1'); + assert.equal(oldVal, undefined); + }); + list1.on('bProp', function (ev, newVal, oldVal) { + assert.equal(newVal, 'FOO', 'bProp newVal on list1'); + assert.equal(oldVal, undefined); + }); + list2.on('aProp', function (ev, newVal, oldVal) { + assert.equal(newVal, 'PROP', 'aProp newVal on list2'); + assert.equal(oldVal, undefined); + }); + list2.on('cProp', function (ev, newVal, oldVal) { + assert.equal(newVal, 'BAR', 'cProp newVal on list2'); + assert.equal(oldVal, undefined); + }); + list1.aProp = 'PROP'; + list1.bProp = 'FOO'; + list2.aProp = 'PROP'; + list2.cProp = 'BAR'; + assert.ok(list1.aMethod, 'list1 aMethod'); + assert.ok(list1.bMethod); + assert.ok(list2.aMethod); + assert.ok(list2.cMethod, 'list2 cMethod'); + }); + QUnit.test('extending DefineList constructor functions - value (#61)', function (assert) { + var AList = DefineList.extend('AList', { aProp: { default: 1 } }); + var BList = AList.extend('BList', {}); + var CList = BList.extend('CList', {}); + var c = new CList([]); + assert.equal(c.aProp, 1, 'got initial value'); + }); + QUnit.test('\'*\' inheritance works (#61)', function (assert) { + 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([{}]); + assert.ok(xl[0] instanceof Account); + }); + QUnit.test('shorthand getter setter (#56)', function (assert) { + 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) { + assert.equal(oldVal, 'Mohamed Cherif'); + assert.equal(newVal, 'Justin Meyer'); + }); + assert.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 (assert) { + var Person = DefineMap.extend({ + id: 'number', + name: 'string' + }); + var addedFuncCalled, removedFuncCalled, theList; + var People = DefineList.extend({ + '#': { + added: function (items, index) { + addedFuncCalled = true; + assert.ok(items, 'items added got passed to added'); + assert.ok(typeof index === 'number', 'index of items was passed to added and is a number'); + assert.ok(items[0].name === 'John', 'Name was correct'); + theList = this; + }, + removed: function (items, index) { + removedFuncCalled = true; + assert.ok(items, 'items added got passed to removed'); + assert.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'; + assert.ok(!addedFuncCalled, 'added function has not been called yet'); + people.push(me); + assert.ok(addedFuncCalled, 'added function was called'); + assert.ok(theList.outsideProp === true && theList instanceof People, 'the list was passed correctly as this to added'); + theList = null; + assert.ok(!removedFuncCalled, 'removed function has not been called yet'); + people.splice(people.indexOf(me), 1); + assert.ok(removedFuncCalled, 'removed function was called'); + assert.ok(theList.outsideProp === true && theList instanceof People, 'the list was passed correctly as this to removed'); + }); + QUnit.test('* vs # (#78)', function (assert) { + var MyList = DefineList.extend({ + '*': 'number', + '#': { + added: function () { + assert.ok(true, 'called on init'); + }, + removed: function () { + }, + type: 'string' + } + }); + var list = new MyList([ + 1, + 2, + 3 + ]); + assert.ok(list[0] === '1', 'converted to string'); + list.set('prop', '4'); + assert.ok(list.prop === 4, 'type converted'); + }); + QUnit.test('Array shorthand uses #', function (assert) { + var MyMap = DefineMap.extend({ 'numbers': ['number'] }); + var map = new MyMap({ + numbers: [ + '1', + '2' + ] + }); + assert.ok(map.numbers[0] === 1, 'converted to number'); + map.numbers.set('prop', '4'); + assert.ok(map.numbers.prop === '4', 'type left alone'); + }); + QUnit.test('replace-with-self lists are diffed properly (can-view-live#10)', function (assert) { + var a = new DefineMap({ name: 'A' }); + var b = new DefineMap({ name: 'B' }); + var c = new DefineMap({ name: 'C' }); + var d = new DefineMap({ name: 'D' }); + assert.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) { + assert.equal(newVals.length, 1, 'list2 added length'); + assert.equal(where, 2, 'list2 added location'); + }); + list2.on('remove', function (ev, oldVals, where) { + assert.equal(oldVals.length, 1, 'list2 removed length'); + assert.equal(where, 2, 'list2 removed location'); + }); + list2.replace([ + a, + b, + d + ]); + }); + QUnit.test('set >= length - triggers length event (#152)', function (assert) { + var l = new DefineList([ + 1, + 2, + 3 + ]); + var batchNum = null; + l.on('add', function (e) { + assert.ok(true, 'add called'); + if (batchNum === null) { + batchNum = e.batchNum; + } else { + assert.equal(batchNum, e.batchNum, 'batch numbers match'); + } + }); + l.on('remove', function (e) { + assert.ok(false, 'remove called'); + if (batchNum === null) { + batchNum = e.batchNum; + } else { + assert.equal(batchNum, e.batchNum, 'batch numbers match'); + } + }); + l.on('length', function (e) { + assert.ok(true, 'length called'); + if (batchNum === null) { + batchNum = e.batchNum; + } else { + assert.equal(batchNum, e.batchNum, 'batch numbers match'); + } + }); + assert.expect(4); + l.set(3, 5); + assert.deepEqual(l.get(), [ + 1, + 2, + 3, + 5 + ], 'updated list'); + }); + QUnit.test('set < length - triggers length event (#150)', function (assert) { + var l = new DefineList([ + 1, + 2, + 3 + ]); + var batchNum = null; + l.on('add', function (e) { + assert.ok(true, 'add called'); + if (batchNum === null) { + batchNum = e.batchNum; + } else { + assert.equal(batchNum, e.batchNum, 'batch numbers match'); + } + }); + l.on('remove', function (e) { + assert.ok(true, 'remove called'); + if (batchNum === null) { + batchNum = e.batchNum; + } else { + assert.equal(batchNum, e.batchNum, 'batch numbers match'); + } + }); + l.on('length', function (e) { + assert.ok(true, 'length called'); + if (batchNum === null) { + batchNum = e.batchNum; + } else { + assert.equal(batchNum, e.batchNum, 'batch numbers match'); + } + }); + assert.expect(6); + l.set(2, 4); + assert.deepEqual(l.get(), [ + 1, + 2, + 4 + ], 'updated list'); + }); + QUnit.test('set/splice are observable', function (assert) { + 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 () { + assert.ok(true); + }); + assert.expect(3); + list.set(3, 5); + list.set(2, 4); + list.splice(1, 1, 1); + }); + QUnit.test('setting length > current (#147)', function (assert) { + var list = new DefineList([ + 1, + 2 + ]); + list.length = 5; + assert.equal(list.length, 5); + assert.equal(list.hasOwnProperty(0), true); + assert.equal(list.hasOwnProperty(1), true); + assert.equal(list.hasOwnProperty(2), true); + assert.equal(list.hasOwnProperty(3), true); + assert.equal(list.hasOwnProperty(4), true); + assert.equal(list.hasOwnProperty(5), false); + }); + QUnit.test('setting length < current (#147)', function (assert) { + var list = new DefineList([ + 1, + 2, + 3, + 4, + 5 + ]); + list.length = 3; + assert.equal(list.length, 3); + assert.equal(list.hasOwnProperty(0), true); + assert.equal(list.hasOwnProperty(1), true); + assert.equal(list.hasOwnProperty(2), true); + assert.equal(list.hasOwnProperty(3), false); + assert.equal(list.hasOwnProperty(4), false); + assert.equal(list.hasOwnProperty(5), false); + }); + QUnit.test('every', function (assert) { + var l = new DefineList([ + { + id: 1, + name: 'Bob' + }, + { + id: 2, + name: 'Bob' + } + ]); + var allBobs = l.every(function (item) { + return item.name === 'Bob'; + }); + assert.ok(allBobs, 'Every works in true case'); + var idOne = l.every(function (item) { + return item.id === 1; + }); + assert.ok(!idOne, 'Every works in false case'); + allBobs = l.every({ name: 'Bob' }); + assert.ok(allBobs, 'Every works in true case'); + idOne = l.every({ + name: 'Bob', + id: 1 + }); + assert.ok(!idOne, 'Every works in false case'); + }); + QUnit.test('some', function (assert) { + var l = new DefineList([ + { + id: 1, + name: 'Alice' + }, + { + id: 2, + name: 'Bob' + } + ]); + var allBobs = l.some(function (item) { + return item.name === 'Bob'; + }); + assert.ok(allBobs, 'Some works in true case'); + var idOne = l.some(function (item) { + return item.name === 'Charlie'; + }); + assert.ok(!idOne, 'Some works in false case'); + allBobs = l.some({ name: 'Bob' }); + assert.ok(allBobs, 'Some works in true case'); + idOne = l.some({ + name: 'Bob', + id: 1 + }); + assert.ok(!idOne, 'Some works in false case'); + }); + QUnit.test('lastIndexOf', function (assert) { + var l = new DefineList([ + { + id: 1, + name: 'Alice' + }, + { + id: 2, + name: 'Bob' + } + ]); + var bobIdx = l.lastIndexOf(l[1]); + assert.equal(bobIdx, 1, 'lastIndexOf found object'); + var charlieIdx = l.lastIndexOf({ + id: 3, + name: 'Charlie' + }); + assert.equal(charlieIdx, -1, 'lastIndexOf not found object'); + l.push(l[1]); + bobIdx = l.lastIndexOf(l[1]); + assert.equal(bobIdx, 2, 'lastIndexOf found last index of duped object'); + }); + QUnit.test('reduce', function (assert) { + 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); + assert.equal(totalScores, 30, 'Reduce works over list'); + }); + QUnit.test('reduceRight', function (assert) { + var l = new DefineList([ + { + id: 1, + name: 'Alice' + }, + { + id: 2, + name: 'Bob' + } + ]); + var concatenatedNames = l.reduceRight(function (string, person) { + return string + person.name; + }, ''); + assert.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); + }); + QUnit.test('works with can-reflect', function (assert) { + var a = new DefineMap({ foo: 4 }); + var b = new DefineList([ + 'foo', + 'bar' + ]); + var c; + assert.equal(canReflect.getKeyValue(b, '0'), 'foo', 'unbound value'); + assert.ok(!canReflect.isValueLike(b), 'isValueLike is false'); + assert.ok(canReflect.isObservableLike(b), 'isObservableLike is true'); + assert.ok(canReflect.isMapLike(b), 'isMapLike is true'); + assert.ok(canReflect.isListLike(b), 'isListLike is false'); + assert.ok(!canReflect.keyHasDependencies(b, 'length'), 'keyHasDependencies -- false'); + define(c = Object.create(b), { + length: { + get: function () { + return a.foo; + } + } + }); + assert.ok(canReflect.getKeyDependencies(c, 'length'), 'dependencies exist'); + assert.ok(canReflect.getKeyDependencies(c, 'length').valueDependencies.has(c._computed.length.compute), 'dependencies returned'); + }); + QUnit.test('can-reflect setKeyValue', function (assert) { + var a = new DefineList([ + 'a', + 'b' + ]); + canReflect.setKeyValue(a, 1, 'c'); + assert.equal(a[1], 'c', 'setKeyValue'); + }); + QUnit.test('can-reflect deleteKeyValue', function (assert) { + var a = new DefineList([ + 'a', + 'b' + ]); + a.set('foo', 'bar'); + canReflect.deleteKeyValue(a, 0); + assert.equal(a[1], undefined, 'last value is now undefined'); + assert.equal(a[0], 'b', 'last value is shifted down'); + canReflect.deleteKeyValue(a, 'foo'); + assert.equal(a.foo, undefined, 'value not included in serial'); + assert.ok(!('foo' in a.get()), 'value not included in serial'); + }); + QUnit.test('can-reflect getKeyDependencies', function (assert) { + var a = new DefineMap({ foo: 4 }); + var b = new DefineList([ + 'foo', + 'bar' + ]); + var c; + assert.ok(!canReflect.getKeyDependencies(b, 'length'), 'No dependencies before binding'); + define(c = Object.create(b), { + length: { + get: function () { + return a.foo; + } + } + }); + assert.ok(canReflect.getKeyDependencies(c, 'length'), 'dependencies exist'); + assert.ok(canReflect.getKeyDependencies(c, 'length').valueDependencies.has(c._computed.length.compute), 'dependencies returned'); + }); + QUnit.test('assign property', function (assert) { + var list = new DefineList([ + 'A', + 'B' + ]); + list.assign({ + count: 0, + skip: 2, + arr: [ + '1', + '2', + '3' + ] + }); + assert.equal(list.get('count'), 0, 'Count set properly'); + list.assign({ + count: 1000, + arr: ['first'] + }); + assert.deepEqual(list.get('arr'), new DefineList(['first']), 'Array is set properly'); + assert.equal(list.get('count'), 1000, 'Count set properly'); + assert.equal(list.get('skip'), 2, 'Skip is unchanged'); + }); + QUnit.test('update property', function (assert) { + var list = new DefineList([ + 'A', + 'B' + ]); + list.update({ + count: 0, + skip: 2 + }); + assert.equal(list.get('count'), 0, 'Count set properly'); + list.update({ count: 1000 }); + assert.equal(list.get('count'), 1000, 'Count set properly'); + assert.equal(list.get('skip'), undefined, 'Skip is changed'); + }); + QUnit.test('assignDeep property', function (assert) { + var list = new DefineList([ + 'A', + 'B' + ]); + list.assignDeep({ + count: 0, + skip: 2, + foo: { + bar: 'zed', + tar: 'yap' + } + }); + assert.equal(list.get('count'), 0, 'Count set properly'); + list.assignDeep({ + count: 1000, + foo: { bar: 'updated' } + }); + assert.equal(list.get('count'), 1000, 'Count set properly'); + assert.equal(list.get('skip'), 2, 'Skip is unchanged'); + assert.propEqual(list.get('foo'), { + bar: 'updated', + tar: 'yap' + }, 'Foo was updated properly'); + }); + QUnit.test('updateDeep property', function (assert) { + var list = new DefineList([ + 'A', + 'B' + ]); + list.updateDeep({ + count: 0, + skip: 2, + foo: { + bar: 'zed', + tar: 'yap' + } + }); + assert.equal(list.get('count'), 0, 'Count set properly'); + list.updateDeep({ count: 1000 }); + assert.equal(list.get('count'), 1000, 'Count set properly'); + assert.equal(list.get('skip'), undefined, 'Skip is set to undefined'); + assert.propEqual(list.get('foo'), undefined, 'Foo is set to undefined'); + }); + QUnit.test('registered symbols', function (assert) { + var a = new DefineMap({ 'a': 'a' }); + assert.ok(a[canSymbol.for('can.isMapLike')], 'can.isMapLike'); + assert.equal(a[canSymbol.for('can.getKeyValue')]('a'), 'a', 'can.getKeyValue'); + a[canSymbol.for('can.setKeyValue')]('a', 'b'); + assert.equal(a.a, 'b', 'can.setKeyValue'); + function handler(val) { + assert.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 (assert) { + var list = new DefineList(['a']); + list.set('length', undefined); + assert.equal(list.length, 1, 'list length is unchanged'); + }); + QUnit.test('cannot set length to a non-number', function (assert) { + var list = new DefineList(['a']); + list.set('length', null); + assert.equal(list.length, 1, 'list length is unchanged'); + list.set('length', 'foo'); + assert.equal(list.length, 1, 'list length is unchanged'); + list.set('length', {}); + assert.equal(list.length, 1, 'list length is unchanged'); + }); + QUnit.test('_length is not enumerable', function (assert) { + assert.ok(!Object.getOwnPropertyDescriptor(new DefineList(), '_length').enumerable, '_length is not enumerable'); + }); + QUnit.test('update with no indexed items sets length to 0', function (assert) { + var list = new DefineList(['a']); + assert.equal(list.length, 1, 'list length is correct before update'); + list.update({ foo: 'bar' }); + assert.equal(list.length, 0, 'list length is correct after update'); + }); + [ + 'length', + '_length' + ].forEach(function (prop) { + QUnit.test('setting ' + prop + ' does not overwrite definition', function (assert) { + 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; + assert.deepEqual(listDef2, listDef, 'descriptor hasn\'t changed'); + }); + }); + QUnit.test('iterator can recover from bad _length', function (assert) { + var list = new DefineList(['a']); + list.set('_length', null); + assert.equal(list._length, null, 'Bad value for _length'); + var iterator = list[canSymbol.iterator](); + var iteration = iterator.next(); + assert.ok(iteration.done, 'Didn\'t fail'); + }); + QUnit.test('onPatches', function (assert) { + 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' + ]); + assert.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 (assert) { + var Type = DefineList.extend({}); + Type[canSymbol.for('can.defineInstanceKey')]('prop', { type: 'number' }); + var t = new Type(); + t.prop = '5'; + assert.equal(t.prop, 5, 'value set'); + }); + QUnit.test('.sort() produces patches (can-stache#498)', function (assert) { + 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(); + assert.deepEqual(calledPatches, PATCHES); + }); + QUnit.test('canReflect.getSchema', function (assert) { + var MyType = DefineMap.extend({ + id: { + identity: true, + type: 'number' + }, + name: 'string' + }); + var MyList = DefineList.extend({ + count: 'number', + '#': MyType + }); + var schema = canReflect.getSchema(MyList); + assert.equal(schema.values, MyType); + }); + QUnit.test('Bound serialized lists update when they change length', function (assert) { + assert.expect(1); + var list = new DefineList(['eggs']); + var obs = new Observation(function () { + return list.serialize(); + }); + function onChange(val) { + assert.deepEqual(val, [ + 'eggs', + 'toast' + ]); + } + canReflect.onValue(obs, onChange); + list.push('toast'); + canReflect.offValue(obs, onChange); + }); + if (typeof Array.prototype.includes === 'function') { + QUnit.test('\'includes\' method basics (#277)', function (assert) { + assert.expect(6); + var emptyList = new DefineList([]); + assert.notOk(emptyList.includes(2)); + var list = new DefineList([ + 1, + 2, + 3 + ]); + assert.ok(list.includes(2)); + assert.notOk(list.includes(4)); + assert.notOk(list.includes(3, 3)); + assert.ok(list.includes(3, -1)); + var nanList = new DefineList([ + 1, + 2, + NaN + ]); + assert.ok(nanList.includes(NaN)); + }); + QUnit.test('\'fromIndex\' is not >= to the array length', function (assert) { + assert.expect(2); + var list = new DefineList([ + 'a', + 'b', + 'c' + ]); + assert.notOk(list.includes('c', 3)); + assert.notOk(list.includes('c', 100)); + }); + QUnit.test('computed index is less than 0', function (assert) { + assert.expect(4); + var list = new DefineList([ + 'a', + 'b', + 'c' + ]); + assert.ok(list.includes('a', -100)); + assert.ok(list.includes('b', -100)); + assert.ok(list.includes('c', -100)); + assert.notOk(list.includes('a', -2)); + }); + QUnit.test('Bound \'includes\' (#277)', function (assert) { + assert.expect(1); + var list = new DefineList(); + var obs = new Observation(function () { + return list.includes('foo'); + }); + function onChange(val) { + assert.ok(val); + } + canReflect.onValue(obs, onChange); + list.push('foo'); + canReflect.offValue(obs, onChange); + }); + } + QUnit.test('Set __inSetup prop #421', function (assert) { + var list = new DefineList([]); + list.set('__inSetup', 'nope'); + assert.equal(list.__inSetup, 'nope'); + }); +}); +/*can-reflect-tests@1.0.0#observables/map-like/instance/on-event-get-set-delete-key*/ +define('can-reflect-tests@1.0.0#observables/map-like/instance/on-event-get-set-delete-key', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-reflect' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var canReflect = require('can-reflect'); + module.exports = function (name, makeInstance) { + QUnit.test(name + ' onEvent, setKeyValue, getKeyValue, deleteKeyValue, getOwnKeys', function (assert) { + var instance = makeInstance(); + var events = []; + assert.notOk(canReflect.isBound(instance), 'not bound'); + canReflect.onEvent(instance, 'prop', function (event) { + events.push(event); + }); + assert.ok(canReflect.isBound(instance), 'bound'); + canReflect.setKeyValue(instance, 'prop', 'FIRST'); + canReflect.getOwnKeys(instance, ['prop'], '.getOwnKeys has set prop'); + assert.equal(canReflect.getKeyValue(instance, 'prop'), 'FIRST', '.getKeyValue'); + canReflect.deleteKeyValue(instance, 'prop'); + assert.equal(canReflect.getKeyValue(instance, 'prop'), undefined, '.deleteKeyValue made it undefined'); + assert.deepEqual(events.map(function (event) { + return { + action: event.action, + value: event.value, + oldValue: event.oldValue, + key: event.key, + target: instance + }; + }), [ + { + action: 'add', + value: 'FIRST', + oldValue: undefined, + key: 'prop', + target: instance + }, + { + action: 'delete', + value: undefined, + oldValue: 'FIRST', + key: 'prop', + target: instance + } + ], 'onEvent'); + assert.deepEqual(canReflect.getOwnEnumerableKeys(instance), [], '.getOwnKeys loses deleted prop'); + }); + }; +}); +/*can-define@2.8.0#map/map-test*/ +define('can-define@2.8.0#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', + 'can-data-types/maybe-string/maybe-string', + 'can-reflect-tests/observables/map-like/instance/on-event-get-set-delete-key' +], 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 MaybeString = require('can-data-types/maybe-string/maybe-string'); + 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 (assert) { + var map = new DefineMap({ prop: 'foo' }); + map.on('prop', function (ev, newVal, oldVal) { + assert.equal(newVal, 'BAR'); + assert.equal(oldVal, 'foo'); + }); + map.prop = 'BAR'; + }); + QUnit.test('creating an instance with nested prop', function (assert) { + var map = new DefineMap({ name: { first: 'Justin' } }); + map.name.on('first', function (ev, newVal, oldVal) { + assert.equal(newVal, 'David'); + assert.equal(oldVal, 'Justin'); + }); + map.name.first = 'David'; + }); + QUnit.test('extending', function (assert) { + var MyMap = DefineMap.extend({ prop: {} }); + var map = new MyMap(); + map.on('prop', function (ev, newVal, oldVal) { + assert.equal(newVal, 'BAR'); + assert.equal(oldVal, undefined); + }); + map.prop = 'BAR'; + }); + QUnit.test('loop only through defined serializable props', function (assert) { + var MyMap = DefineMap.extend({ + propA: {}, + propB: { serialize: false }, + propC: { + get: function () { + return this.propA; + } + } + }); + var inst = new MyMap({ + propA: 1, + propB: 2 + }); + assert.deepEqual(Object.keys(inst.get()), ['propA']); + }); + QUnit.test('get and set can setup expandos', function (assert) { + var map = new DefineMap(); + var oi = new Observation(function () { + return map.get('foo'); + }); + canReflect.onValue(oi, function (newVal) { + assert.equal(newVal, 'bar', 'updated to bar'); + canReflect.offValue(oi); + }); + map.set('foo', 'bar'); + }); + QUnit.test('default settings', function (assert) { + var MyMap = DefineMap.extend({ + '*': 'string', + foo: {} + }); + var m = new MyMap(); + m.set('foo', 123); + assert.ok(m.get('foo') === '123'); + }); + QUnit.test('default settings on unsealed', function (assert) { + var MyMap = DefineMap.extend({ seal: false }, { '*': 'string' }); + var m = new MyMap(); + m.set('foo', 123); + assert.ok(m.get('foo') === '123'); + }); + if (!System.isEnv('production')) { + QUnit.test('extends sealed objects (#48)', function (assert) { + 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) { + assert.ok(false, 'map1 not sealed'); + } else { + assert.ok(true, 'map1 sealed - silent failure'); + } + } catch (ex) { + assert.ok(true, 'map1 sealed'); + } + assert.equal(map1.name, 'computed Justin', 'map1.name property is computed'); + var map2 = new Map2({ name: 'Brian' }); + try { + map2.foo = 'bar'; + if (map2.foo) { + assert.ok(true, 'map2 not sealed'); + } else { + assert.ok(false, 'map2 sealed'); + } + } catch (ex) { + assert.ok(false, 'map2 sealed'); + } + assert.equal(map2.name, 'computed Brian', 'map2.name property is computed'); + var map3 = new Map3({ name: 'Curtis' }); + try { + map3.foo = 'bar'; + if (map3.foo) { + assert.ok(false, 'map3 not sealed'); + } else { + assert.ok(true, 'map3 sealed'); + } + } catch (ex) { + assert.ok(true, 'map3 sealed'); + } + assert.equal(map3.name, 'computed Curtis', 'map3.name property is computed'); + }); + } + QUnit.test('get with dynamically added properties', function (assert) { + var map = new DefineMap(); + map.set('a', 1); + map.set('b', 2); + assert.deepEqual(map.get(), { + a: 1, + b: 2 + }); + }); + QUnit.test('set multiple props', function (assert) { + var map = new DefineMap(); + map.assign({ + a: 0, + b: 2 + }); + assert.deepEqual(map.get(), { + a: 0, + b: 2 + }, 'added props'); + map.update({ a: 2 }); + assert.deepEqual(map.get(), { a: 2 }, 'removed b'); + map.assign({ foo: { bar: 'VALUE' } }); + assert.deepEqual(map.get(), { + foo: { bar: 'VALUE' }, + a: 2 + }, 'works nested'); + }); + QUnit.test('serialize responds to added props', function (assert) { + var map = new DefineMap(); + var oi = new Observation(function () { + return map.serialize(); + }); + canReflect.onValue(oi, function (newVal) { + assert.deepEqual(newVal, { + a: 1, + b: 2 + }, 'updated right'); + canReflect.offValue(oi); + }); + map.assign({ + a: 1, + b: 2 + }); + }); + QUnit.test('initialize an undefined property', function (assert) { + var MyMap = DefineMap.extend({ seal: false }, {}); + var instance = new MyMap({ foo: 'bar' }); + assert.equal(instance.foo, 'bar'); + }); + QUnit.test('set an already initialized null property', function (assert) { + var map = new DefineMap({ foo: null }); + map.assign({ foo: null }); + assert.equal(map.foo, null); + }); + QUnit.test('creating a new key doesn\'t cause two changes', function (assert) { + assert.expect(1); + var map = new DefineMap(); + var oi = new Observation(function () { + return map.serialize(); + }); + canReflect.onValue(oi, function (newVal) { + assert.deepEqual(newVal, { a: 1 }, 'updated right'); + canReflect.offValue(oi); + }); + map.set('a', 1); + }); + QUnit.test('setting nested object', function (assert) { + var m = new DefineMap({}); + m.assign({ foo: {} }); + m.assign({ foo: {} }); + assert.deepEqual(m.get(), { foo: {} }); + }); + QUnit.test('passing a DefineMap to DefineMap (#33)', function (assert) { + var MyMap = DefineMap.extend({ foo: 'observable' }); + var m = new MyMap({ + foo: {}, + bar: {} + }); + var m2 = new MyMap(m); + assert.deepEqual(m.get(), m2.get()); + assert.ok(m.foo === m2.foo, 'defined props the same'); + assert.ok(m.bar === m2.bar, 'expando props the same'); + }); + QUnit.test('serialize: function works (#38)', function (assert) { + 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 + }); + assert.ok(myMap.somethingRef instanceof Something); + assert.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 + }); + assert.deepEqual(myMap2.serialize(), { + foo: '1', + bar: '2' + }, 'serialize: function on default works'); + }); + QUnit.test('get will not create properties', function (assert) { + var method = function () { + }; + var MyMap = DefineMap.extend({ method: method }); + var m = new MyMap(); + m.get('foo'); + assert.equal(m.get('method'), method); + }); + QUnit.test('Properties are enumerable', function (assert) { + assert.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) { + assert.equal(key, 'foo'); + assert.equal(value, 'bar'); + } else { + assert.equal(key, 'baz'); + assert.equal(value, 'qux'); + } + i++; + }); + }); + QUnit.test('Getters are not enumerable', function (assert) { + assert.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) { + assert.equal(key, 'foo'); + assert.equal(value, 'bar'); + }); + }); + QUnit.test('extending DefineMap constructor functions (#18)', function (assert) { + 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) { + assert.equal(newVal, 'PROP'); + assert.equal(oldVal, undefined); + }); + map.on('bProp', function (ev, newVal, oldVal) { + assert.equal(newVal, 'FOO'); + assert.equal(oldVal, undefined); + }); + map.on('cProp', function (ev, newVal, oldVal) { + assert.equal(newVal, 'BAR'); + assert.equal(oldVal, undefined); + }); + map.aProp = 'PROP'; + map.bProp = 'FOO'; + map.cProp = 'BAR'; + assert.ok(map.aMethod); + assert.ok(map.bMethod); + assert.ok(map.cMethod); + }); + QUnit.test('extending DefineMap constructor functions more than once (#18)', function (assert) { + 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) { + assert.equal(newVal, 'PROP', 'aProp newVal on map1'); + assert.equal(oldVal, undefined); + }); + map1.on('bProp', function (ev, newVal, oldVal) { + assert.equal(newVal, 'FOO', 'bProp newVal on map1'); + assert.equal(oldVal, undefined); + }); + map2.on('aProp', function (ev, newVal, oldVal) { + assert.equal(newVal, 'PROP', 'aProp newVal on map2'); + assert.equal(oldVal, undefined); + }); + map2.on('cProp', function (ev, newVal, oldVal) { + assert.equal(newVal, 'BAR', 'cProp newVal on map2'); + assert.equal(oldVal, undefined); + }); + map1.aProp = 'PROP'; + map1.bProp = 'FOO'; + map2.aProp = 'PROP'; + map2.cProp = 'BAR'; + assert.ok(map1.aMethod, 'map1 aMethod'); + assert.ok(map1.bMethod); + assert.ok(map2.aMethod); + assert.ok(map2.cMethod, 'map2 cMethod'); + }); + QUnit.test('extending DefineMap constructor functions - value (#18)', function (assert) { + var AType = DefineMap.extend('AType', { aProp: { default: 1 } }); + var BType = AType.extend('BType', {}); + var CType = BType.extend('CType', {}); + var c = new CType(); + assert.equal(c.aProp, 1, 'got initial value'); + }); + QUnit.test('copying DefineMap excludes constructor', function (assert) { + var AType = DefineMap.extend('AType', { aProp: { default: 1 } }); + var a = new AType(); + var b = assign({}, a); + assert.notEqual(a.constructor, b.constructor, 'Constructor prop not copied'); + assert.equal(a.aProp, b.aProp, 'Other values are unaffected'); + }); + QUnit.test('cloning from non-defined map excludes special keys on setup', function (assert) { + var MyType = DefineMap.extend({}); + var a = new MyType({ 'foo': 'bar' }); + var b = new DefineMap(a); + assert.notEqual(a.constructor, b.constructor, 'Constructor prop not copied'); + assert.notEqual(a._data, b._data, '_data prop not copied'); + assert.equal(a.foo, b.foo, 'Other props copied'); + }); + QUnit.test('copying from .set() excludes special keys', function (assert) { + var MyType = DefineMap.extend({}); + var a = new MyType({ + 'foo': 'bar', + 'existing': 'newVal' + }); + var b = new DefineMap({ 'existing': 'oldVal' }); + b.assign(a); + assert.notEqual(a.constructor, b.constructor, 'Constructor prop not copied'); + assert.notEqual(a._data, b._data, '_data prop not copied'); + assert.equal(a.foo, b.foo, 'NEw props copied'); + }); + QUnit.test('copying with assign() excludes special keys', function (assert) { + var a = { + _data: {}, + 'foo': 'bar', + 'existing': 'neVal' + }; + var b = new DefineMap({ 'existing': 'oldVal' }, false); + canReflect.assignMap(b, a); + assert.notEqual(a._data, b._data, '_data prop not copied'); + assert.equal(a.foo, b.foo, 'New props copied'); + assert.equal(a.existing, b.existing, 'Existing props copied'); + }); + QUnit.test('shorthand getter setter (#56)', function (assert) { + 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) { + assert.equal(oldVal, 'Mohamed Cherif'); + assert.equal(newVal, 'Justin Meyer'); + }); + assert.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 (assert) { + var VM = DefineMap.extend({ computeProp: { type: 'compute' } }); + var vmNull = new VM({ computeProp: null }); + assert.equal(vmNull.get('computeProp'), null, 'computeProp is null, no error thrown'); + var vmUndef = new VM({ computeProp: undefined }); + assert.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 (assert) { + var Base = DefineMap.extend({ baseProp: 'string' }); + var Inheriting = Base.extend(); + var inherting = new Inheriting(); + inherting.set('baseProp', 'value'); + assert.equal(inherting.baseProp, 'value', 'set prop'); + }); + if (sealWorks && System.env.indexOf('production') < 0) { + QUnit.test('setting not defined property', function (assert) { + var MyMap = DefineMap.extend({ prop: {} }); + var mymap = new MyMap(); + try { + mymap.notdefined = 'value'; + assert.ok(false, 'no error'); + } catch (e) { + assert.ok(true, 'error thrown'); + } + }); + } + QUnit.test('.extend errors when re-defining a property (#117)', function (assert) { + 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'; + } + } + }); + assert.ok(true, 'extended without errors'); + }); + QUnit.test('.value functions should not be observable', function (assert) { + 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'; + assert.equal(count, 1); + }); + QUnit.test('.value values are overwritten by props in DefineMap construction', function (assert) { + var Foo = DefineMap.extend({ bar: { default: 'baz' } }); + var foo = new Foo({ bar: 'quux' }); + assert.equal(foo.bar, 'quux', 'Value set properly'); + }); + QUnit.test('can-reflect reflections work with DefineMap', function (assert) { + var b = new DefineMap({ 'foo': 'bar' }); + var c = new (DefineMap.extend({ + 'baz': { + get: function () { + return b.foo; + } + } + }))({ + 'foo': 'bar', + thud: 'baz' + }); + assert.equal(canReflect.getKeyValue(b, 'foo'), 'bar', 'unbound value'); + var handler = function (newValue) { + assert.equal(newValue, 'quux', 'observed new value'); + canReflect.offKeyValue(c, 'baz', handler); + }; + assert.ok(!canReflect.isValueLike(c), 'isValueLike is false'); + assert.ok(canReflect.isObservableLike(c), 'isObservableLike is true'); + assert.ok(canReflect.isMapLike(c), 'isMapLike is true'); + assert.ok(!canReflect.isListLike(c), 'isListLike is false'); + assert.ok(!canReflect.keyHasDependencies(b, 'foo'), 'keyHasDependencies -- false'); + canReflect.onKeyValue(c, 'baz', handler); + canReflect.onKeyValue(c, 'thud', handler); + assert.ok(canReflect.keyHasDependencies(c, 'baz'), 'keyHasDependencies -- true'); + b.foo = 'quux'; + c.thud = 'quux'; + assert.equal(canReflect.getKeyValue(c, 'baz'), 'quux', 'bound value'); + b.foo = 'thud'; + c.baz = 'jeek'; + }); + QUnit.test('can-reflect setKeyValue', function (assert) { + var a = new DefineMap({ 'a': 'b' }); + canReflect.setKeyValue(a, 'a', 'c'); + assert.equal(a.a, 'c', 'setKeyValue'); + }); + QUnit.test('can-reflect deleteKeyValue', function (assert) { + var a = new DefineMap({ 'a': 'b' }); + canReflect.deleteKeyValue(a, 'a'); + assert.equal(a.a, undefined, 'value is now undefined'); + assert.ok(!('a' in a.get()), 'value not included in serial'); + }); + QUnit.test('can-reflect getKeyDependencies', function (assert) { + var a = new DefineMap({ 'a': 'a' }); + var b = new (DefineMap.extend({ + 'a': { + get: function () { + return a.a; + } + } + }))(); + assert.ok(canReflect.getKeyDependencies(b, 'a'), 'dependencies exist'); + assert.ok(!canReflect.getKeyDependencies(b, 'b'), 'no dependencies exist for unknown value'); + assert.ok(canReflect.getKeyDependencies(b, 'a').valueDependencies.has(b._computed.a.compute), 'dependencies returned'); + }); + QUnit.test('can-reflect assign', function (assert) { + var aData = { 'a': 'b' }; + var bData = { 'b': 'c' }; + var a = new DefineMap(aData); + var b = new DefineMap(bData); + canReflect.assign(a, b); + assert.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 (assert) { + 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); + assert.equal(baz.quux, 'jeek', 'New definitions successful'); + assert.equal(baz.plonk, 'waldo', 'New computed definitions successful'); + assert.equal(baz.baz, 'thud', 'Old definitions still available'); + }); + if (!System.isEnv('production')) { + QUnit.test('redefines still not allowed on sealed objects', function (assert) { + assert.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) { + assert.ok(/is not extensible/i.test(e.message), 'Sealed object throws on data property defines'); + assert.ok(!Object.getOwnPropertyDescriptor(baz, 'quux'), 'nothing set on object'); + assert.ok(!Object.getOwnPropertyDescriptor(baz._data, 'quux'), 'nothing set on _data'); + } + try { + define(baz, { + plonk: { + get: function () { + return 'waldo'; + } + } + }, baz._define); + } catch (e) { + assert.ok(/is not extensible/i.test(e.message), 'Sealed object throws on computed property defines'); + assert.ok(!Object.getOwnPropertyDescriptor(baz, 'plonk'), 'nothing set on object'); + assert.ok(!Object.getOwnPropertyDescriptor(baz._computed, 'plonk'), 'nothing set on _computed'); + } + }); + } + QUnit.test('Call .get() when a nested object has its own get method', function (assert) { + 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(); + assert.equal(data.request.prop, 22, 'obj did get()'); + }); + QUnit.test('DefineMap short-hand Type (#221)', function (assert) { + var Child = DefineMap.extend('child', { other: DefineMap }); + var c = new Child(); + c.other = { prop: 'hello' }; + assert.ok(c.other instanceof DefineMap, 'is a DefineMap'); + }); + QUnit.test('non-Object constructor', function (assert) { + var Constructor = DefineMap.extend(); + assert.ok(!isPlainObject(new DefineMap()), 'instance of DefineMap is not a plain object'); + assert.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 (assert) { + 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) { + assert.equal(newVal, 'bar', 'updated to bar'); + }); + map.set('foo', 'bar'); + }); + QUnit.test('Observation bound to async getter updates correctly (canjs#3541)', function (assert) { + 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) { + assert.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 (assert) { + assert.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 } }); + assert.equal(finishErrorCheck(), 2); + }); + canTestHelpers.devOnlyTest('Setting a default value to a constructor type generates a warning', function (assert) { + assert.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 } }); + assert.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 (assert) { + assert.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]/; + assert.ok(rightProp.test(actual.split(' ')[0])); + assert.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' + }); + assert.equal(finishErrorCheck(), 2); + }); + QUnit.test('Improper shorthand properties are not set', function (assert) { + var VM = DefineMap.extend({ + prop01: 0, + prop02: function () { + }, + prop03: 'some random string' + }); + assert.equal(VM.prototype._define.methods.prop01, undefined); + assert.equal(typeof VM.prototype._define.methods.prop02, 'function'); + assert.equal(VM.prototype._define.methods.prop03, undefined); + }); + QUnit.test('onKeyValue sets up computed values', function (assert) { + 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 () { + }); + assert.deepEqual(fullNameCalls, ['J M']); + }); + QUnit.test('async getters derived from other properties should have correct keyDependencies', function (assert) { + 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 () { + }); + assert.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 (assert) { + var VM = DefineMap.extend({}); + var vm = new VM(); + try { + vm.set('fooxyz', 'bar'); + } catch (error) { + if (sealDoesErrorWithPropertyName) { + assert.ok(error.message.indexOf('fooxyz') !== -1, 'Set property error with property name should be thrown'); + } else { + assert.ok(true, 'Set property error should be thrown'); + } + } + }); + canTestHelpers.devOnlyTest('can.hasKey and can.hasOwnKey (#303) (#412)', 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'); + var map = new DefineMap({ expandoKey: undefined }); + assert.equal(map[hasKeySymbol]('expandoKey'), true, 'map.hasKey(\'expandoKey\') (#412)'); + }); + 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 (assert) { + var MyMap = DefineMap.extend({ prop: { value: 'a string' } }); + var my = new MyMap(); + assert.equal(my.prop, 'a string', 'works'); + }); + QUnit.test('canReflect.getSchema', function (assert) { + var StringIgnoreCase = canReflect.assignSymbols({}, { + 'can.new': function (value) { + return value.toLowerCase(); + } + }); + var MyType = DefineMap.extend({ + id: { + identity: true, + type: 'number' + }, + name: 'string', + foo: { serialize: false }, + lowerCase: StringIgnoreCase, + text: MaybeString, + maybeString_type: { type: MaybeString }, + maybeString_Type: { Type: MaybeString } + }); + var schema = canReflect.getSchema(MyType); + assert.deepEqual(schema.identity, ['id'], 'right identity'); + assert.deepEqual(Object.keys(schema.keys), [ + 'id', + 'name', + 'lowerCase', + 'text', + 'maybeString_type', + 'maybeString_Type' + ], 'right key names'); + assert.equal(canReflect.convert('1', schema.keys.id), 1, 'converted to number'); + assert.equal(canReflect.convert(3, schema.keys.id), '3', 'converted to number'); + assert.equal(schema.keys.name, MaybeString, ' \'string\' -> MaybeString'); + assert.equal(schema.keys.lowerCase, StringIgnoreCase, 'StringIgnoreCase'); + assert.equal(schema.keys.text, MaybeString, 'MaybeString'); + assert.equal(schema.keys.maybeString_type, MaybeString, '{type: MaybeString}'); + assert.equal(schema.keys.maybeString_Type, MaybeString, '{Type: MaybeString}'); + }); + QUnit.test('use can.new and can.serialize for conversion', function (assert) { + 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' }); + assert.equal(todo.status, 'new', 'converted during set'); + assert.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() }); + assert.ok(todo2.due instanceof Date, 'converted to a date instance'); + var res = todo2.serialize(); + assert.deepEqual(res, { due: date }, 'serialized to a date?'); + }); + QUnit.test('make sure stringOrObservable works', function (assert) { + var Type = DefineMap.extend({ val: 'stringOrObservable' }); + var type = new Type({ val: 'foo' }); + assert.equal(type.val, 'foo', 'works'); + }); + QUnit.test('primitive types work with val: Type', function (assert) { + var UpperCase = {}; + UpperCase[canSymbol.for('can.new')] = function (val) { + return val.toUpperCase(); + }; + var Type = DefineMap.extend({ val: UpperCase }); + var type = new Type({ val: 'works' }); + assert.equal(type.val, 'WORKS', 'it worked'); + }); + QUnit.test('primitive types work with val: {Type: Type}', function (assert) { + 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' }); + assert.equal(type.val, 'WORKS', 'it worked'); + }); + QUnit.test('primitive types work with val: {type: Type}', function (assert) { + 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' }); + assert.equal(type.val, 'WORKS', 'it worked'); + }); + QUnit.test('ownKeys works on basic DefineMaps', function (assert) { + var map = new DefineMap({ + first: 'Jane', + last: 'Doe' + }); + var keys = canReflect.getOwnKeys(map); + assert.equal(keys.length, 2, 'There are 2 keys'); + }); + QUnit.test('deleteKey works (#351)', function (assert) { + var map = new DefineMap({ foo: 'bar' }); + assert.deepEqual(canReflect.getOwnKeys(map), ['foo']); + map.set('zed', 'ted'); + assert.deepEqual(canReflect.getOwnKeys(map), [ + 'foo', + 'zed' + ]); + map.deleteKey('zed'); + assert.deepEqual(canReflect.getOwnKeys(map), ['foo']); + map.deleteKey('foo'); + assert.deepEqual(canReflect.getOwnKeys(map), []); + map.set('foo', 'bar'); + map = new DefineMap({ foo: 'bar' }, true); + map.deleteKey('foo'); + assert.equal(map.foo, undefined, 'prop set to undefined'); + }); + QUnit.test('makes sure observation add is called (#393)', function (assert) { + var map = new DefineMap({ foo: 'bar' }); + canReflect.deleteKeyValue(map, 'foo'); + ObservationRecorder.start(); + (function () { + return map.foo; + }()); + var result = ObservationRecorder.stop(); + assert.deepEqual(canReflect.toArray(result.keyDependencies.get(map)), ['foo'], 'toArray'); + }); + QUnit.test('type called with `this` as the map (#349)', function (assert) { + var Type = DefineMap.extend({ + foo: { + type: function () { + assert.equal(Type, this.constructor, 'got the right this'); + return 5; + }, + default: 4 + } + }); + var map = new Type(); + assert.equal(map.foo, 5); + }); + QUnit.test('expandos use default type (#383)', function (assert) { + var AllNumbers = DefineMap.extend({ '*': { type: 'number' } }); + var someNumbers = new AllNumbers({ version: '24' }); + assert.ok(someNumbers.version === 24, 'is 24'); + }); + QUnit.test('do not enumerate anything other than key properties (#369)', function (assert) { + 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 assert.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; + } + assert.deepEqual(props, { + aProp: true, + anExpando: true, + aMethod: true + }); + }); + QUnit.test('Properties added via defineInstanceKey are observable', function (assert) { + 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) { + assert.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 (assert) { + 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' }); + assert.equal(second.myPage, 'two', 'Runs the getter correctly'); + }); + QUnit.test('setup should be called (#395)', function (assert) { + 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(); + assert.deepEqual(calls, [ + base, + supa + ], 'setup called'); + }); + QUnit.test('Set new prop to undefined #408', function (assert) { + var obj = new DefineMap({}); + var PATCHES = [ + [{ + type: 'add', + key: 'foo', + value: undefined + }], + [{ + type: 'set', + key: 'foo', + value: 'bar' + }] + ]; + var calledPatches = []; + var handler = function (patches) { + calledPatches.push(patches); + }; + obj[canSymbol.for('can.onPatches')](handler, 'notify'); + obj.set('foo', undefined); + obj.set('foo', 'bar'); + assert.deepEqual(calledPatches, PATCHES); + }); + QUnit.test('Set __inSetup prop #421', function (assert) { + var map = new DefineMap({}); + map.set('__inSetup', 'nope'); + assert.equal(map.__inSetup, 'nope'); + }); + QUnit.test('\'*\' wildcard type definitions that use constructors works for expandos #425', function (assert) { + var MyType = function MyType() { + }; + MyType.prototype = {}; + var OtherType = DefineMap.extend({ seal: false }, { '*': MyType }); + var map = new OtherType(); + map.set('foo', {}); + var foo = map.get('foo'); + assert.ok(foo instanceof MyType); + }); + QUnit.test('\'*\' wildcard type definitions that use DefineMap constructors works for expandos #425', function (assert) { + var MyType = DefineMap.extend({}); + var OtherType = DefineMap.extend({ seal: false }, { '*': MyType }); + var map = new OtherType(); + map.set('foo', {}); + var foo = map.get('foo'); + assert.ok(foo instanceof MyType); + }); + require('can-reflect-tests/observables/map-like/instance/on-event-get-set-delete-key')('DefineMap', function () { + return new DefineMap(); + }); +}); +/*can-define@2.8.0#test/test-list-and-map*/ +define('can-define@2.8.0#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 (assert) { + var items = new DefineMap({ + people: [ + { name: 'Justin' }, + { name: 'Brian' } + ], + count: 1000 + }); + assert.ok(items.people instanceof DefineList, 'people is list'); + assert.ok(items.people.item(0) instanceof DefineMap, '1st object is Map'); + assert.ok(items.people.item(1) instanceof DefineMap, '2nd object is Map'); + assert.equal(items.people.item(1).name, 'Brian', '2nd object\'s name is right'); + assert.equal(items.count, 1000, 'count is number'); + }); + QUnit.test('basic type', function (assert) { + assert.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(); + assert.deepEqual(Object.keys(t), [], 'no keys'); + var array = []; + t.arrayWithAddedItem = array; + assert.deepEqual(array, ['item'], 'updated array'); + assert.equal(t.arrayWithAddedItem, array, 'leave value as array'); + t.listWithAddedItem = []; + assert.ok(t.listWithAddedItem instanceof DefineList, 'convert to CanList'); + assert.equal(t.listWithAddedItem[0], 'item', 'has item in it'); + var observation = new Observation(function () { + return t.listWithAddedItem.attr('length'); + }); + canReflect.onValue(observation, function (newVal) { + assert.equal(newVal, 2, 'got a length change'); + }); + t.listWithAddedItem.push('another item'); + }); + QUnit.test('serialize works', function (assert) { + var Person = DefineMap.extend({ + first: 'string', + last: 'string' + }); + var People = DefineList.extend({ '*': Person }); + var people = new People([{ + first: 'j', + last: 'm' + }]); + assert.deepEqual(people.serialize(), [{ + first: 'j', + last: 'm' + }]); + }); + QUnit.test('Extended Map with empty def converts to default Observables', function (assert) { + var School = DefineMap.extend({ + students: {}, + teacher: {} + }); + var school = new School(); + school.students = [{ name: 'J' }]; + school.teacher = { name: 'M' }; + assert.ok(school.students instanceof DefineList, 'converted to DefineList'); + assert.ok(school.teacher instanceof DefineMap, 'converted to DefineMap'); + }); + QUnit.test('default \'observable\' type prevents Type from working (#29)', function (assert) { + 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 }] }); + assert.ok(m.l[0] instanceof M, 'is instance'); + assert.equal(m.l[0].id, 5, 'correct props'); + }); + QUnit.test('inline DefineList Type', function (assert) { + var M = DefineMap.extend('M', { id: 'number' }); + var MyMap = DefineMap.extend({ l: { Type: [M] } }); + var m = new MyMap({ l: [{ id: 5 }] }); + assert.ok(m.l[0] instanceof M, 'is instance'); + assert.equal(m.l[0].id, 5, 'correct props'); + }); + QUnit.test('recursively `get`s (#31)', function (assert) { + 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(); + assert.ok(Array.isArray(res.l), 'is a plain array'); + assert.ok(isPlainObject(res.l[0]), 'plain object'); + }); + QUnit.test('DefineList trigger deprecation warning when set with Map.set (#93)', function (assert) { + assert.expect(0); + var map = new DefineMap({ things: [{ foo: 'bar' }] }); + map.things.attr = function () { + assert.ok(false, 'attr should not be called'); + }; + map.assign({ things: [{ baz: 'luhrmann' }] }); + }); + QUnit.test('Value generator can read other properties', function (assert) { + 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 '; + assert.equal(map.firstLetter, 'A', prefix + 'traditional can.Map style property definition'); + assert.equal(map.firstNumber, 1, prefix + 'traditional can.Map style property definition'); + assert.equal(map.middleLetter, 'E', prefix + 'define plugin style default property definition'); + assert.equal(map.middleNumber, 5, prefix + 'define plugin style default property definition'); + assert.equal(map.lastLetter, 'I', prefix + 'define plugin style generated default property definition'); + assert.equal(map.lastNumber, 9, prefix + 'define plugin style generated default property definition'); + }); + QUnit.test('value and get (#1521)', function (assert) { + 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({}); + assert.equal(map.size, 2); + }); + QUnit.test('Assign value on map', function (assert) { + 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' } + }); + assert.equal(obj.list.length, 1, 'list length should be 1'); + assert.propEqual(obj.foo, { bar: 'zed' }, 'foo.bar is set correctly'); + assert.equal(obj.name, 'CanJS', 'name is unchanged'); + }); + QUnit.test('Update value on a map', function (assert) { + 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' } + }); + assert.equal(obj.list.length, 1, 'list length should be 1'); + assert.equal(obj.foo.bar, 'zed', 'foo.bar is set correctly'); + assert.equal(obj.name, undefined, 'name is removed'); + }); + QUnit.test('Deep assign a map', function (assert) { + var MyConstruct = DefineMap.extend({ + list: DefineList, + name: 'string' + }); + var obj = new MyConstruct({ + list: [ + 'data', + 'data', + 'data' + ], + name: 'Test Name' + }); + assert.equal(obj.list.length, 3, 'list length should be 3'); + obj.assignDeep({ list: ['something'] }); + assert.equal(obj.name, 'Test Name', 'Name property is still intact'); + assert.equal(obj.list[0], 'something', 'the first element in the list should be updated'); + }); + QUnit.test('Deep updating a map', function (assert) { + var MyConstruct = DefineMap.extend({ + list: DefineList, + name: 'string' + }); + var obj = new MyConstruct({ + list: [ + 'data', + 'data', + 'data' + ], + name: 'Test Name' + }); + assert.equal(obj.list.length, 3, 'list length should be 3'); + obj.updateDeep({ list: ['something'] }); + assert.equal(obj.name, undefined, 'Name property has been reset'); + assert.equal(obj.list[0], 'something', 'the first element of the list should be updated'); + }); + QUnit.test('assignDeep', function (assert) { + 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 }]); + assert.deepEqual(people.serialize(), [ + { + name: 'Justin', + age: 36 + }, + { + name: 'Payal', + age: 35 + } + ], 'assigned right'); + }); + QUnit.test('DefineMap fires \'set\' event when a new property is added (#400)', function (assert) { + var counter = 0; + var vm = new DefineMap({}); + canReflect.onPatches(vm, function (patch) { + if (counter === 0) { + assert.equal(patch[0].type, 'add', 'dispatched add correctly'); + } else { + assert.equal(patch[0].type, 'set', 'dispatched set correctly'); + } + counter++; + }); + vm.set('name', 'Matt'); + vm.set('name', 'Justin'); + }); +}); +/*can-define@2.8.0#test/test-value-resolve*/ +define('can-define@2.8.0#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 (assert) { + 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(); + assert.equal(me.nameChangeCount, 0, 'unbound value'); + me.name = 'first'; + assert.equal(me.nameChangeCount, 0, 'unbound value'); + me.on('nameChangeCount', function (ev, newVal, oldVal) { + assert.equal(newVal, 1, 'updated count'); + assert.equal(oldVal, 0, 'updated count from old value'); + }); + me.name = 'second'; + assert.equal(me.nameChangeCount, 1, 'bound value'); + }); + QUnit.test('fullName getter the hard way', function (assert) { + assert.expect(3); + 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' + }); + assert.equal(me.fullName, 'Justin Meyer', 'unbound value'); + var handler = function (ev, newVal, oldVal) { + assert.equal(newVal, 'Ramiya Meyer', 'event newVal'); + assert.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 (assert) { + 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 }); + assert.equal(vm.tasksLength, 0, 'empty tasks, unbound'); + vm.tasks = [ + 'chore 1', + 'chore 2' + ]; + assert.equal(vm.tasksLength, 2, 'tasks, unbound'); + var lengths = []; + vm.on('tasksLength', function (ev, newLength) { + lengths.push(newLength); + }); + assert.equal(vm.tasksLength, 2, '2 tasks, bound'); + vm.tasks.push('chore 3'); + var originalTasks = vm.tasks; + assert.equal(vm.tasksLength, 3, '3 tasks, bound, after push to source'); + vm.tasks = ['one chore']; + assert.equal(vm.tasksLength, 1, '1 tasks, bound, after replace array'); + assert.notOk(canReflect.isBound(originalTasks), 'not bound on original'); + assert.deepEqual(lengths, [ + 3, + 1 + ], 'length changes are right'); + }); + QUnit.test('batches produce one result', function (assert) { + assert.expect(2); + 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) { + assert.equal(newVal, 'Ramiya Shah', 'event newVal'); + assert.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 (assert) { + 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'; + assert.equal(locator.city, null, 'changing the state sets the city'); + }); + QUnit.test('location vm with setter', function (assert) { + 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' + }); + assert.equal(locator.city, 'Chicago', 'init to Chicago'); + locator.on('city', function () { + }); + locator.state = 'CA'; + assert.equal(locator.city, null, 'changing the state sets the city'); + locator.city = 'San Jose'; + assert.equal(locator.city, 'San Jose', 'changing the state sets the city'); + }); + QUnit.test('events should not be fired when resolve is not called', function (assert) { + 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({}); + assert.equal(nums.oddNumber, 5, 'initial value is 5'); + nums.on('oddNumber', function (ev, newVal) { + assert.equal(newVal % 2, 1, 'event dispatched for ' + newVal); + }); + nums.oddNumber = 7; + nums.oddNumber = 8; + }); + QUnit.test('reading properties does not leak out', function (assert) { + 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(); + assert.equal(records.keyDependencies.size, 0, 'there are no key dependencies'); + }); +}); +/*can-define@2.8.0#test/test*/ +define('can-define@2.8.0#test/test', [ + 'require', + 'exports', + 'module', + './test-define-only', + '../list/list-test', + '../map/map-test', + './test-list-and-map', + './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-value-resolve'); +}); +/*can-stache-bindings@4.10.9#test/helpers*/ +define('can-stache-bindings@4.10.9#test/helpers', [ + 'require', + 'exports', + 'module', + 'can-globals', + 'can-dom-events', + 'can-dom-mutate', + 'can-dom-mutate/node', + 'can-dom-data', + 'can-vdom/make-document/make-document', + 'can-test-helpers' +], 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'); + var makeDocument = require('can-vdom/make-document/make-document'); + var canTestHelpers = require('can-test-helpers'); + var helpers = { + makeQUnitModule: function (name, doc, enableMO) { + QUnit.module(name, { + beforeEach: 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); + } + }, + afterEach: function (assert) { + if (doc !== document) { + doc.body.removeChild(this.fixture); + } + var done = assert.async(); + helpers.afterMutation(function () { + globals.deleteKeyValue('document'); + globals.deleteKeyValue('MutationObserver'); + var fixture = document.getElementById('qunit-fixture'); + while (fixture && fixture.hasChildNodes()) { + domData.delete(fixture.lastChild); + fixture.removeChild(fixture.lastChild); + } + done(); + }); + } + }); + }, + 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) { + var noop = function () { + }; + helpers.makeQUnitModule(name + ' - dom', document, true); + makeTest(name + ' - dom', document, true, QUnit.test, noop); + makeTest(name + ' - dom - dev only', document, true, noop, canTestHelpers.dev.devOnlyTest); + var doc = makeDocument(); + helpers.makeQUnitModule(name + ' - vdom', doc, false); + makeTest(name + ' - vdom', doc, false, noop, noop); + }, + 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.10.9#test/mock-component-simple-map*/ +define('can-stache-bindings@4.10.9#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', + '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'); + 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(el, 'preventDataBindings', true); + if (proto.template) { + var shadowScope = componentTagData.scope.add(viewModel); + domData.set(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.10.9#test/colon/basics-test*/ +define('can-stache-bindings@4.10.9#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'); + function siblingsDataToInfo(siblingData) { + return { + parent: siblingData.parent.source, + child: siblingData.child.source, + childEvent: siblingData.child.event, + parentToChild: siblingData.parent.exports, + childToParent: siblingData.child.exports, + childName: siblingData.child.name, + parentName: siblingData.parent.name, + bindingAttributeName: siblingData.bindingAttributeName, + initializeValues: siblingData.initializeValues, + syncChildWithParent: siblingData.parent.syncSibling + }; + } + testHelpers.makeTests('can-stache-bindings - colon - basics', function (name, doc, enableMO) { + QUnit.test('basics', function (assert) { + assert.expect(5); + 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 () { + assert.ok(true, 'on:vmevent bindings work'); + } + }); + var parent = new MySimpleMap({ + valueA: 'A', + valueB: 'B', + valueC: 'C' + }); + template(parent); + assert.deepEqual(parent.get(), { + valueA: 'A', + valueB: 'toParent', + valueC: 'C' + }, 'initial scope values correct'); + assert.deepEqual(viewModel.get(), { + toChild: 'A', + toParent: 'toParent', + twoWay: 'C' + }, 'initial VM values correct'); + parent.set({ + valueA: 'a', + valueB: 'b', + valueC: 'c' + }); + assert.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' + }); + assert.deepEqual(parent.get(), { + valueA: 'a', + valueB: 'to-parent', + valueC: 'two-way' + }, 'vm set scope values correct'); + viewModel.dispatch({ type: 'vmevent' }); + }); + QUnit.test('getSiblingBindingData', function (assert) { + var info = stacheBindings.getSiblingBindingData({ + name: 'foo-ed:from', + value: 'bar' + }); + assert.deepEqual(siblingsDataToInfo(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.getSiblingBindingData({ + name: 'foo-ed:bind', + value: 'bar' + }); + assert.deepEqual(siblingsDataToInfo(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.getSiblingBindingData({ + name: 'foo-ed:to', + value: 'bar' + }); + assert.deepEqual(siblingsDataToInfo(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.getSiblingBindingData({ + name: 'foo-ed:from', + value: 'bar' + }, { favorViewModel: true }); + assert.deepEqual(siblingsDataToInfo(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.getSiblingBindingData({ + name: 'foo-ed:bind', + value: 'bar' + }, { favorViewModel: true }); + assert.deepEqual(siblingsDataToInfo(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.getSiblingBindingData({ + name: 'foo-ed:to', + value: 'bar' + }, { favorViewModel: true }); + assert.deepEqual(siblingsDataToInfo(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'); + }); + QUnit.test('getSiblingBindingData for vm:', function (assert) { + var info = stacheBindings.getSiblingBindingData({ + name: 'vm:foo-ed:from', + value: 'bar' + }); + assert.deepEqual(siblingsDataToInfo(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.getSiblingBindingData({ + name: 'vm:foo-ed:bind', + value: 'bar' + }); + assert.deepEqual(siblingsDataToInfo(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.getSiblingBindingData({ + name: 'vm:foo-ed:to', + value: 'bar' + }); + assert.deepEqual(siblingsDataToInfo(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.getSiblingBindingData({ + name: 'vm:foo-ed:from', + value: 'bar' + }, { favorViewModel: true }); + assert.deepEqual(siblingsDataToInfo(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.getSiblingBindingData({ + name: 'vm:foo-ed:bind', + value: 'bar' + }, { favorViewModel: true }); + assert.deepEqual(siblingsDataToInfo(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.getSiblingBindingData({ + name: 'vm:foo-ed:to', + value: 'bar' + }, { favorViewModel: true }); + assert.deepEqual(siblingsDataToInfo(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'); + }); + QUnit.test('getSiblingBindingData for el:', function (assert) { + var info = stacheBindings.getSiblingBindingData({ + name: 'el:foo-ed:from', + value: 'bar' + }); + assert.deepEqual(siblingsDataToInfo(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.getSiblingBindingData({ + name: 'el:foo-ed:bind', + value: 'bar' + }); + assert.deepEqual(siblingsDataToInfo(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.getSiblingBindingData({ + name: 'el:foo-ed:to', + value: 'bar' + }); + assert.deepEqual(siblingsDataToInfo(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.getSiblingBindingData({ + name: 'el:foo-ed:from', + value: 'bar' + }, null, null, null, true); + assert.deepEqual(siblingsDataToInfo(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.getSiblingBindingData({ + name: 'el:foo-ed:bind', + value: 'bar' + }, null, null, null, true); + assert.deepEqual(siblingsDataToInfo(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.getSiblingBindingData({ + name: 'el:foo-ed:to', + value: 'bar' + }, null, null, null, true); + assert.deepEqual(siblingsDataToInfo(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('getSiblingBindingData works for value:to:on:click (#269)', function (assert) { + var info = stacheBindings.getSiblingBindingData({ + name: 'value:to:on:click', + value: 'bar' + }); + assert.deepEqual(siblingsDataToInfo(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 (assert) { + var name = encoder.encode('goToHome:to'); + var info = stacheBindings.getSiblingBindingData({ + name: name, + value: 'bar' + }); + assert.deepEqual(siblingsDataToInfo(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 (assert) { + 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); + assert.equal(teardown(), 1, 'warning shown'); + }); + QUnit.test('parent stache is able to teardown child bindings (#278)', function (assert) { + 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); + assert.equal(input.value, 'VALUE', 'value set initially'); + map.set('value', ''); + assert.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'); + assert.equal(input.value, 'second', 'value should have been updated'); + input.value = 'third'; + domEvents.dispatch(input, 'change'); + assert.equal(map.get('value'), 'third', 'map should have been updated'); + done(); + }); + }); + }); +}); +/*can-stache-bindings@4.10.9#test/colon/element-test*/ +define('can-stache-bindings@4.10.9#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 (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]; + assert.equal(input.value, '', 'input value set correctly if key does not exist in map'); + map.set('age', '30'); + assert.equal(input.value, '30', 'input value set correctly'); + map.set('age', '31'); + assert.equal(input.value, '31', 'input value update correctly'); + input.value = '32'; + domEvents.dispatch(input, 'change'); + assert.equal(map.get('age'), '32', 'updated from input'); + }); + QUnit.test(' el:prop:to/:from/:bind work (#280)', function (assert) { + 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]; + assert.equal(scope.attr('scope1'), '1', 'el:value:to - scope value set from attribute'); + inputTo.value = '4'; + domEvents.dispatch(inputTo, 'change'); + assert.equal(scope.attr('scope1'), '4', 'el:value:to - scope updated when attribute changed'); + scope.attr('scope1', 'scope4'); + assert.equal(inputTo.value, '4', 'el:value:to - attribute not updated when scope changed'); + assert.equal(inputFrom.value, 'scope2', 'el:value:from - attribute set from scope'); + inputFrom.value = 'scope5'; + domEvents.dispatch(inputFrom, 'change'); + assert.equal(scope.attr('scope2'), 'scope2', 'el:value:from - scope not updated when attribute changed'); + scope.attr('scope2', 'scope6'); + assert.equal(inputFrom.value, 'scope6', 'el:value:from - attribute updated when scope changed'); + assert.equal(inputBind.value, 'scope3', 'el:value:bind - attribute set from scope prop (parent -> child wins)'); + inputBind.value = 'scope6'; + domEvents.dispatch(inputBind, 'change'); + assert.equal(scope.attr('scope3'), 'scope6', 'el:value:bind - scope updated when attribute changed'); + scope.attr('scope3', 'scope7'); + assert.equal(inputBind.value, 'scope7', 'el:value:bind - attribute updated when scope changed'); + }); + if (System.env !== 'canjs-test') { + QUnit.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 () { + assert.equal(input.value, 'Justin', 'input value set correctly if key does not exist in map'); + map.set('propName', 'last'); + testHelpers.afterMutation(function () { + assert.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 () { + assert.equal(map.get('last'), 'Lueke', 'updated from input'); + done(); + }); + }); + }); + }); + } + QUnit.test('value:bind compute rejects new value (#887)', function (assert) { + 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'); + assert.equal(compute.get(), 30, 'Still the old value'); + assert.equal(input.value, '30', 'Text input has also not changed'); + }); + QUnit.test('value:from works with camelCase and kebab-case properties', function (assert) { + 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]; + assert.equal(camelPropInput.value, '', 'input bound to camelCase prop value set correctly if camelCase key does not exist in map'); + assert.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'); + assert.equal(camelPropInput.value, '30', 'input bound to camelCase prop value set correctly when camelCase prop changes'); + assert.equal(kebabPropInput.value, '', 'input bound to kebab-case prop value not updated when camelCase prop changes'); + map.attr('theProp', '31'); + assert.equal(camelPropInput.value, '31', 'input bound to camelCase prop value updated correctly when camelCase prop changes'); + assert.ok(!kebabPropInput.value, 'input bound to kebab-case prop value not updated when camelCase prop changes'); + camelPropInput.value = '32'; + domEvents.dispatch(camelPropInput, 'change'); + assert.equal(map.attr('theProp'), '31', 'camelCase prop NOT updated when input bound to camelCase prop changes'); + assert.ok(!map.attr('the-prop'), 'kebabCase prop NOT updated when input bound to camelCase prop changes'); + map.attr('the-prop', '33'); + assert.equal(kebabPropInput.value, '33', 'input bound to kebab-case prop value set correctly when kebab-case prop changes'); + assert.equal(camelPropInput.value, '32', 'input bound to camelCase prop value not updated when kebab-case prop changes'); + map.attr('the-prop', '34'); + assert.equal(kebabPropInput.value, '34', 'input bound to kebab-case prop value updated correctly when kebab-case prop changes'); + assert.equal(camelPropInput.value, '32', 'input bound to camelCase prop value not updated when kebab-case prop changes'); + kebabPropInput.value = '35'; + domEvents.dispatch(kebabPropInput, 'change'); + assert.equal(map.attr('the-prop'), '34', 'kebab-case prop NOT updated from input bound to kebab-case prop'); + assert.equal(map.attr('theProp'), '31', 'camelCase prop NOT updated from input bound to kebab-case prop'); + }); + QUnit.test('value:to works with camelCase and kebab-case properties', function (assert) { + 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'); + assert.equal(map.attr('theProp'), '32', 'camelCaseProp updated from input bound to camelCase Prop'); + assert.ok(!map.attr('the-prop'), 'kebabCaseProp NOT updated from input bound to camelCase Prop'); + map.attr('theProp', '30'); + assert.equal(camelPropInput.value, '32', 'input bound to camelCase Prop value NOT updated when camelCase prop changes'); + assert.ok(!kebabPropInput.value, 'input bound to kebabCase Prop value NOT updated when camelCase prop changes'); + kebabPropInput.value = '33'; + domEvents.dispatch(kebabPropInput, 'change'); + assert.equal(map.attr('the-prop'), '33', 'kebabCaseProp updated from input bound to kebabCase Prop'); + assert.equal(map.attr('theProp'), '30', 'camelCaseProp NOT updated from input bound to camelCase Prop'); + map.attr('theProp', '34'); + assert.equal(kebabPropInput.value, '33', 'input bound to kebabCase Prop value NOT updated when kebabCase prop changes'); + assert.equal(camelPropInput.value, '32', 'input bound to camelCase Prop value NOT updated when kebabCase prop changes'); + }); + QUnit.test('value:bind works with camelCase and kebab-case properties', function (assert) { + 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'); + assert.equal(map.attr('theProp'), '32', 'camelCaseProp updated from input bound to camelCase Prop'); + assert.ok(!map.attr('the-prop'), 'kebabCaseProp NOT updated from input bound to camelCase Prop'); + map.attr('theProp', '30'); + assert.equal(camelPropInput.value, '30', 'input bound to camelCase Prop value updated when camelCase prop changes'); + assert.ok(!kebabPropInput.value, 'input bound to kebabCase Prop value NOT updated when camelCase prop changes'); + kebabPropInput.value = '33'; + domEvents.dispatch(kebabPropInput, 'change'); + assert.equal(map.attr('the-prop'), '33', 'kebabCaseProp updated from input bound to kebabCase Prop'); + assert.equal(map.attr('theProp'), '30', 'camelCaseProp NOT updated from input bound to camelCase Prop'); + map.attr('theProp', '34'); + assert.equal(kebabPropInput.value, '33', 'input bound to kebabCase Prop value NOT updated when kebabCase prop changes'); + assert.equal(camelPropInput.value, '34', 'input bound to camelCase Prop value updated when kebabCase prop changes'); + }); + QUnit.test('Bracket expression with dot and no explicit root and value:bind', function (assert) { + 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]; + assert.equal(input.value, '', 'input value set correctly if key does not exist in map'); + data.set('two.hops', 'slide to the left'); + assert.equal(input.value, 'slide to the left', 'input value set correctly'); + data.set('two.hops', 'slide to the right'); + assert.equal(input.value, 'slide to the right', 'input value update correctly'); + input.value = 'REVERSE REVERSE'; + domEvents.dispatch(input, 'change'); + assert.equal(data.get('two.hops'), 'REVERSE REVERSE', 'updated from input'); + }); + QUnit.test('Bracket expression with colon and no explicit root and value:bind', function (assert) { + 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]; + assert.equal(input.value, '', 'input value set correctly if key does not exist in map'); + data.set('two:hops', 'slide to the left'); + assert.equal(input.value, 'slide to the left', 'input value set correctly'); + data.set('two:hops', 'slide to the right'); + assert.equal(input.value, 'slide to the right', 'input value update correctly'); + input.value = 'REVERSE REVERSE'; + domEvents.dispatch(input, 'change'); + assert.equal(data.get('two:hops'), 'REVERSE REVERSE', 'updated from input'); + }); + QUnit.test('el:prop:to/:from/:bind work (#280)', function (assert) { + 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]; + assert.equal(scope.attr('scope1'), '1', 'el:value:to - scope value set from attribute'); + inputTo.value = '4'; + domEvents.dispatch(inputTo, 'change'); + assert.equal(scope.attr('scope1'), '4', 'el:value:to - scope updated when attribute changed'); + scope.attr('scope1', 'scope4'); + assert.equal(inputTo.value, '4', 'el:value:to - attribute not updated when scope changed'); + assert.equal(inputFrom.value, 'scope2', 'el:value:from - attribute set from scope'); + inputFrom.value = 'scope5'; + domEvents.dispatch(inputFrom, 'change'); + assert.equal(scope.attr('scope2'), 'scope2', 'el:value:from - scope not updated when attribute changed'); + scope.attr('scope2', 'scope6'); + assert.equal(inputFrom.value, 'scope6', 'el:value:from - attribute updated when scope changed'); + assert.equal(inputBind.value, 'scope3', 'el:value:bind - attribute set from scope prop (parent -> child wins)'); + inputBind.value = 'scope6'; + domEvents.dispatch(inputBind, 'change'); + assert.equal(scope.attr('scope3'), 'scope6', 'el:value:bind - scope updated when attribute changed'); + scope.attr('scope3', 'scope7'); + assert.equal(inputBind.value, 'scope7', 'el:value:bind - attribute updated when scope changed'); + }); + QUnit.test(' two-way - DOM - input text (#1700)', 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]; + assert.equal(input.value, '', 'input value set correctly if key does not exist in map'); + map.attr('age', '30'); + var done = assert.async(); + testHelpers.afterMutation(function () { + assert.equal(input.value, '30', 'input value set correctly'); + map.attr('age', '31'); + testHelpers.afterMutation(function () { + assert.equal(input.value, '31', 'input value update correctly'); + input.value = '32'; + domEvents.dispatch(input, 'change'); + testHelpers.afterMutation(function () { + done(); + assert.equal(map.attr('age'), '32', 'updated from input'); + }); + }); + }); + }); + QUnit.test('errors subproperties of undefined properties (#298)', function (assert) { + try { + stache('')(); + assert.ok(true, 'renderer was made without error'); + } catch (e) { + assert.ok(false, e.message); + } + }); + QUnit.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)); + }); + QUnit.test('value:bind memory leak (#2270)', function (assert) { + var template = stache('
      '); + var vm = new SimpleMap({ foo: '' }); + var frag = template(vm); + var ta = this.fixture; + domMutateNode.appendChild.call(ta, frag); + var done = assert.async(); + 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) { + assert.ok(true, 'no bindings'); + done(); + } else { + checkCount++; + if (checkCount > 5) { + assert.ok(false, 'lifecycle bindings still existed after timeout'); + return done(); + } + setTimeout(checkLifecycleBindings, 1000); + } + }; + checkLifecycleBindings(); + }); + }); + }); + QUnit.test('converters work (#2299)', function (assert) { + 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); + assert.equal(frag.firstChild.value, '25'); + assert.equal(map.get('age'), 25); + map.set('age', 33); + assert.equal(frag.firstChild.value, '33'); + assert.equal(map.get('age'), 33); + frag.firstChild.value = '1'; + domEvents.dispatch(frag.firstChild, 'change'); + var done = assert.async(); + testHelpers.afterMutation(function () { + done(); + assert.equal(frag.firstChild.value, '1'); + assert.equal(map.get('age'), 1); + }); + }); + testIfRealDocument(' checked:bind should trigger a radiochange event for radio buttons', function (assert) { + 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'); + assert.equal(text(fooText), 'false', 'foo text is false'); + assert.equal(text(barText), 'true', 'bar text is true'); + assert.equal(data.get('foo'), false); + assert.equal(data.get('bar'), true); + }); + QUnit.test(' change event handler set up when binding on radiochange (#206)', function (assert) { + var template = stache(''); + var map = new SimpleMap({ attending: false }); + var frag = template(map); + var input = frag.firstChild; + input.checked = true; + domEvents.dispatch(input, 'change'); + assert.equal(map.get('attending'), true, 'now it is true'); + }); + QUnit.test(' one-way - DOM - with undefined (#135)', function (assert) { + var data = new SimpleMap({ completed: undefined }), frag = stache('')(data); + domMutateNode.appendChild.call(this.fixture, frag); + var input = this.fixture.getElementsByTagName('input')[0]; + assert.equal(input.checked, false, 'checkbox value should be false for undefined'); + }); + QUnit.test(' two-way - DOM - with truthy and falsy values binds to checkbox (#1700)', function (assert) { + var data = new SimpleMap({ completed: 1 }), frag = stache('')(data); + domMutateNode.appendChild.call(this.fixture, frag); + var input = this.fixture.getElementsByTagName('input')[0]; + assert.equal(input.checked, true, 'checkbox value bound (via attr check)'); + data.attr('completed', 0); + var done = assert.async(); + testHelpers.afterMutation(function () { + done(); + assert.equal(input.checked, false, 'checkbox value bound (via attr check)'); + }); + }); + QUnit.test(' checkboxes with checked:bind bind properly (#628)', function (assert) { + var data = new SimpleMap({ completed: true }), frag = stache('')(data); + domMutateNode.appendChild.call(this.fixture, frag); + var input = this.fixture.getElementsByTagName('input')[0]; + assert.equal(input.checked, data.get('completed'), 'checkbox value bound (via attr check)'); + data.attr('completed', false); + assert.equal(input.checked, data.get('completed'), 'checkbox value bound (via attr uncheck)'); + input.checked = true; + domEvents.dispatch(input, 'change'); + assert.equal(input.checked, true, 'checkbox value bound (via check)'); + assert.equal(data.get('completed'), true, 'checkbox value bound (via check)'); + input.checked = false; + domEvents.dispatch(input, 'change'); + assert.equal(input.checked, false, 'checkbox value bound (via uncheck)'); + assert.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 + }); + var done = assert.async(); + var select = frag.firstChild; + var options = select.getElementsByTagName('option'); + testHelpers.afterMutation(function () { + assert.ok(options[1].selected, 'value is initially selected'); + values.set([ + '7', + '2', + '5', + '4' + ]); + testHelpers.afterMutation(function () { + assert.ok(options[1].selected, 'after changing options, value should still be selected'); + done(); + }); + }); + }); + testIfRealDocument(''); + var map = new SimpleMap(); + var frag = template(map); + var ta = this.fixture; + ta.appendChild(frag); + var select = ta.childNodes.item(0); + assert.equal(select.selectedIndex, 0, 'Got selected index'); + }); + testIfRealDocument(''); + var map = new SimpleMap({}); + var frag = renderer(map); + assert.equal(frag.firstChild.selectedIndex, 0, 'undefined <- {($first value)}: selectedIndex = 0'); + map.attr('key', 'notfoo'); + var done = assert.async(); + testHelpers.afterMutation(function () { + assert.equal(frag.firstChild.selectedIndex, -1, 'notfoo: selectedIndex = -1'); + map.attr('key', 'foo'); + assert.strictEqual(frag.firstChild.selectedIndex, 0, 'foo: selectedIndex = 0'); + map.attr('key', 'notbar'); + testHelpers.afterMutation(function () { + done(); + assert.equal(frag.firstChild.selectedIndex, -1, 'notbar: selectedIndex = -1'); + map.attr('key', 'bar'); + assert.strictEqual(frag.firstChild.selectedIndex, 1, 'bar: selectedIndex = 1'); + map.attr('key', 'bar'); + assert.strictEqual(frag.firstChild.selectedIndex, 1, 'bar (no change): selectedIndex = 1'); + }); + }); + }); + QUnit.test(' ' + '{{#each options}} {{/each}} '); + var frag = template(data); + assert.equal(frag.firstChild.getElementsByTagName('option')[0].selected, false, 'The first empty value is not selected'); + assert.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' + } + ]) + }); + var done = assert.async(); + var frag = template(map); + var ta = this.fixture; + ta.appendChild(frag); + var select = ta.getElementsByTagName('select')[0], options = select.getElementsByTagName('option'); + testHelpers.afterMutation(function () { + assert.ok(options[0].selected, 'red should be set initially'); + assert.ok(options[1].selected, 'green should be set initially'); + assert.ok(!options[2].selected, 'blue should not be set initially'); + done(); + }); + }); + QUnit.test('' + '{{#each countries}}' + '' + '{{/each}}' + ''); + var frag = template(data); + var select = frag.firstChild; + var done = assert.async(); + testHelpers.afterMutation(function () { + data.get('countries').replace([]); + testHelpers.afterMutation(function () { + data.attr('countries').replace(countries); + assert.equal(data.attr('countryCode'), 'US', 'country kept as USA'); + testHelpers.afterMutation(function () { + assert.ok(select.getElementsByTagName('option')[1].selected, 'USA still selected'); + }); + done(); + }); + }); + }); + testIfRealDocument('' + '' + '' + ''); + var map = new SimpleMap({ color: 'red' }); + var frag = template(map); + var ta = this.fixture; + ta.appendChild(frag); + var inputs = ta.getElementsByTagName('select'); + assert.equal(inputs[0].value, 'red', 'default value set'); + map.set('color', 'green'); + assert.equal(inputs[0].value, 'green', 'alternate value set'); + canReflect.each(ta.getElementsByTagName('option'), function (opt) { + if (opt.value === 'red') { + opt.selected = 'selected'; + } + }); + assert.equal(map.get('color'), 'green', 'not yet updated from input'); + domEvents.dispatch(inputs[0], 'change'); + assert.equal(map.get('color'), 'red', 'updated from input'); + canReflect.each(ta.getElementsByTagName('option'), function (opt) { + if (opt.value === 'green') { + opt.selected = 'selected'; + } + }); + assert.equal(map.get('color'), 'red', 'not yet updated from input'); + domEvents.dispatch(inputs[0], 'change'); + assert.equal(map.get('color'), 'green', 'updated from input'); + }); + testIfRealDocument('' + '' + '' + '' + ''); + var list = new DefineList(); + var done = assert.async(); + 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'); + assert.deepEqual(list.get(), ['red'], 'A DefineList value is set even if none existed'); + options[1].selected = true; + domEvents.dispatch(select, 'change'); + assert.deepEqual(list.get(), [ + 'red', + 'green' + ], 'Adds items to the list'); + options[0].selected = false; + domEvents.dispatch(select, 'change'); + assert.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); + done(); + }, 1); + }); + QUnit.test('' + '{{#countries}}' + '' + '{{/countries}}' + ''); + var frag = template(data); + var select = frag.firstChild; + var done = assert.async(); + testHelpers.afterMutation(function () { + data.get('countries').replace([]); + testHelpers.afterMutation(function () { + data.get('countries').replace(countries); + assert.equal(data.get('countryCode'), 'US', 'country kept as USA'); + testHelpers.afterMutation(function () { + assert.ok(select.getElementsByTagName('option')[1].selected, 'USA still selected'); + }); + done(); + }); + }); + }); + testIfRealDocument('' + '{{#each countries}}' + '' + '{{/each}}' + ''); + template(data); + var done = assert.async(); + testHelpers.afterMutation(function () { + data.attr('countries').replace([]); + testHelpers.afterMutation(function () { + assert.equal(data.get('countryCode'), undefined, 'countryCode set to undefined'); + done(); + }); + }); + }); + testIfRealDocument('' + '' + '{{#each people}}{{/each}}' + '' + ''); + var people = new DefineList([ + 'Justin', + 'Zed', + 'Tom', + 'Paula' + ]); + var vm = new SimpleMap({ + person: 'Brian', + people: people + }); + var done = assert.async(); + vm.on('person', function (ev, newVal, oldVal) { + assert.ok(false, 'person attribute should not change'); + }); + var frag = template(vm); + assert.equal(vm.attr('person'), 'Brian', 'Person is still set'); + testHelpers.afterMutation(function () { + people.push('Brian'); + testHelpers.afterMutation(function () { + var select = frag.firstChild; + assert.ok(select.lastChild.selected, 'New child should be selected'); + done(); + }); + }); + }); + QUnit.test('' + '{{#each countries}}' + '' + '{{/each}}' + ''); + var data = new SimpleMap({ + countryCode: 'US', + countries: new DefineList(countries) + }); + var frag = template(data); + data.set('countryCode', 'IND'); + var done = assert.async(); + testHelpers.afterMutation(function () { + done(); + assert.equal(frag.firstChild.value, 'IND', 'got last updated value'); + }); + }); + testIfRealDocument('' + '' + '' + '' + '' + '' + ''); + var map = new SimpleMap({ + 'color-1': null, + 'color-2': undefined, + 'color-3': '' + }); + var done = assert.async(); + 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 () { + assert.ok(!nullInputOptions[0].selected, 'default (null) value set'); + assert.ok(undefinedInputOptions[0].selected, 'default (undefined) value set'); + assert.ok(stringInputOptions[0].selected, 'default (\'\') value set'); + done(); + }); + }); + testIfRealDocument(''); + var map = new SimpleMap({ key: null }); + var frag = template(map); + var select = frag.childNodes.item(0); + testHelpers.afterMutation(function () { + assert.equal(select.selectedIndex, -1, 'selectedIndex is 0 because no value exists on the map'); + assert.equal(map.get('key'), null, 'The map\'s value property is set to the select\'s value'); + done(); + }); + var done = assert.async(); + }); + testIfRealDocument(''); + var map = new SimpleMap(); + var frag = template(map); + var select = frag.childNodes.item(0); + testHelpers.afterMutation(function () { + assert.equal(select.selectedIndex, 0, 'selectedIndex is 0 because no value exists on the map'); + assert.equal(map.attr('value'), 'One', 'The map\'s value property is set to the select\'s value'); + done(); + }); + var done = assert.async(); + }); + testIfRealDocument('Bi-directional binding among sibling components, new syntax (#325)', function (assert) { + 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]); + assert.equal(frag.childNodes[0].childNodes[0].nodeValue, '', 'demoContext person is empty'); + assert.equal(frag.childNodes[1].childNodes[0].childNodes[0].nodeValue, 'John', 'source-component person is default'); + assert.equal(frag.childNodes[2].childNodes[1].childNodes[0].nodeValue, '', 'clear-button person is empty'); + sourceComponentVM.person = 'Bob'; + assert.equal(frag.childNodes[0].childNodes[0].nodeValue, 'Bob', 'demoContext person set correctly'); + assert.equal(frag.childNodes[1].childNodes[0].childNodes[0].nodeValue, 'Bob', 'source-component person set correctly'); + assert.equal(frag.childNodes[2].childNodes[1].childNodes[0].nodeValue, 'Bob', 'clear-button person set correctly'); + clearButtonVM.clearPerson(); + assert.equal(frag.childNodes[0].childNodes[0].nodeValue, '', 'demoContext person set correctly'); + assert.equal(frag.childNodes[1].childNodes[0].childNodes[0].nodeValue, 'John', 'source-component person set correctly'); + assert.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 (assert) { + 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); + assert.equal(demoContext.person.name, 'Kevin', 'source-component has correct name set'); + }); + QUnit.test('this:to works', function (assert) { + var template = stache(''); + var map = new SimpleMap({ input: null }); + var frag = template(map); + var input = frag.firstChild; + assert.equal(input, map.get('input'), 'set the input'); + }); + }); +}); +/*can-event-dom-enter@2.2.1#can-event-dom-enter*/ +define('can-event-dom-enter@2.2.1#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.10.9#test/colon/event-test*/ +define('can-stache-bindings@4.10.9#test/colon/event-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + '../helpers', + 'can-test-helpers', + 'can-stache-bindings', + 'can-stache', + '../mock-component-simple-map', + 'can-view-callbacks', + 'can-simple-map', + 'can-define/list/list', + 'can-simple-observable', + 'can-view-model', + 'can-reflect', + 'can-symbol', + 'can-dom-data', + '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'); + var canTestHelpers = require('can-test-helpers'); + require('can-stache-bindings'); + var stache = require('can-stache'); + var MockComponent = require('../mock-component-simple-map'); + var viewCallbacks = require('can-view-callbacks'); + 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 canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var domData = require('can-dom-data'); + 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, testIfRealDocument, testIfRealDocumentInDev) { + QUnit.test('on:enter', function (assert) { + var enterEvent = require('can-event-dom-enter'); + var undo = domEvents.addEvent(enterEvent); + var template = stache(''); + var called = 0; + var frag = template({ + update: function () { + called++; + assert.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'); + }); + QUnit.test('two bindings on one element call back the correct method', function (assert) { + assert.expect(2); + var template = stache(''); + var callingFirst = false, callingSecond = false; + var frag = template({ + first: function () { + assert.ok(callingFirst, 'called first'); + }, + second: function () { + assert.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' }); + }); + QUnit.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); + }); + QUnit.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 () { + assert.equal(clickHandlerCount, 0, 'click handler not called'); + done(); + }); + }); + QUnit.test('can listen to camelCase events using on:', function (assert) { + var done = assert.async(); + assert.expect(1); + var map = new SimpleMap({ someProp: 'foo' }); + map.someMethod = function () { + done(); + assert.ok(true); + }; + var template = stache('
      '); + template(map); + map.set('someProp', 'baz'); + }); + QUnit.test('can listen to kebab-case events using on:', function (assert) { + var done = assert.async(); + assert.expect(1); + var map = new SimpleMap({ 'some-prop': 'foo' }); + map.someMethod = function () { + done(); + assert.ok(true); + }; + var template = stache('
      '); + template(map); + map.set('some-prop', 'baz'); + }); + QUnit.test('can bind to property on scope using :by:', function (assert) { + var done = assert.async(); + assert.expect(1); + MockComponent.extend({ tag: 'view-model-able' }); + var template = stache(''); + var map = new SimpleMap({ obj: new SimpleMap({ prop: 'Mercury' }) }); + map.someMethod = function (args) { + done(); + assert.equal(args[0], 'Venus', 'method called'); + }; + template(map); + map.get('obj').set('prop', 'Venus'); + }); + QUnit.test('can bind to entire scope using :by:this', function (assert) { + var done = assert.async(); + assert.expect(1); + MockComponent.extend({ tag: 'view-model-able' }); + var template = stache(''); + var map = new SimpleMap({ prop: 'Mercury' }); + map.someMethod = function (newVal) { + done(); + assert.equal(newVal, 'Venus', 'method called'); + }; + template(map); + map.set('prop', 'Venus'); + }); + QUnit.test('can bind to viewModel using on:vm:prop', function (assert) { + var done = assert.async(); + assert.expect(1); + var map = new SimpleMap({ prop: 'Mercury' }); + var MySimpleMap = SimpleMap.extend({ + someMethod: function (newVal) { + done(); + assert.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'); + }); + QUnit.test('can bind to element using on:el:prop', function (assert) { + var done = assert.async(); + assert.expect(1); + var map = new SimpleMap({ prop: 'Mercury' }); + var MySimpleMap = SimpleMap.extend({ + someMethod: function () { + done(); + assert.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'); + }); + QUnit.test('call expressions work (#208)', function (assert) { + assert.expect(2); + stache.registerHelper('addTwo', function (arg) { + return arg + 2; + }); + stache.registerHelper('helperWithArgs', function (arg) { + assert.equal(arg, 3, 'got the helper'); + assert.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 (assert) { + var flip = false; + var template = stache('
      Test
      '); + var frag = template({ + flip: function () { + flip = true; + }, + test: true + }); + domEvents.dispatch(frag.firstChild, 'foo'); + assert.ok(flip, 'Plain object method successfully called'); + }); + QUnit.test('scope.arguments gives the event arguments', function (assert) { + var template = stache(''); + var MyMap = SimpleMap.extend({ + doSomething: function (ev, args) { + assert.equal(args[0], ev, 'default arg is ev'); + } + }); + var frag = template(new MyMap()); + var button = frag.firstChild; + domEvents.dispatch(button, 'click'); + }); + QUnit.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(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 (assert) { + MockComponent.extend({ + tag: 'viewmodel-binding', + viewModel: { + makeMyEvent: function () { + this.dispatch('myevent'); + } + } + }); + var frag = stache('')({ + doSomething: function () { + assert.ok(true, 'called!'); + } + }); + canViewModel(frag.firstChild).makeMyEvent(); + }); + QUnit.test('event handlers should run in mutateQueue (#444)', function (assert) { + 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'); + assert.ok(true, 'no errors'); + }); + QUnit.test('support simple setters', function (assert) { + 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' }); + assert.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' }); + assert.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' }); + assert.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' }); + assert.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; + assert.equal(typeof button.viewModel.get('clicked'), 'function', 'has function'); + domEvents.dispatch(myButton, { type: 'click' }); + assert.equal(map.get('clickCount'), 1, 'function got called'); + }); + testIfRealDocument('on:click:value:to on button (#484)', function (assert) { + var template = stache(''); + var map = new SimpleMap({ myProp: 1 }); + var frag = template(map); + var button = frag.firstChild; + assert.equal(map.get('myProp'), 1, 'initial value'); + domEvents.dispatch(button, 'click'); + assert.equal(map.get('myProp'), 2, 'set from value'); + }); + QUnit.test('Registering events on nullish context with :by should register an observation on the scope and properly teardown all listeners on removal', function (assert) { + var map = new SimpleMap({ + user: null, + doSomething: function () { + assert.ok(true); + } + }); + var user = new SimpleMap({ name: 'Michael' }); + var fragment = stache('
      ')(map); + var div = fragment.firstChild; + domMutateNode.appendChild.call(this.fixture, fragment); + assert.equal(canReflect.isBound(map), true); + map.set('user', user); + assert.equal(canReflect.isBound(user), true); + domMutateNode.removeChild.call(this.fixture, div); + testHelpers.afterMutation(function () { + assert.equal(canReflect.isBound(map), false); + assert.equal(canReflect.isBound(user), false); + }); + }); + QUnit.test('Registering events on nullish context with :by should switch bindings when the context is defined and teardiwn old listener', function (assert) { + var map = new SimpleMap({ + user: null, + doSomething: function () { + assert.ok(true); + } + }); + var user1 = new SimpleMap({ name: 'Michael' }); + var user2 = new SimpleMap({ name: 'Justin' }); + stache('
      ')(map); + assert.equal(canReflect.isBound(map), true); + map.set('user', user1); + assert.equal(canReflect.isBound(user1), true); + assert.equal(canReflect.isBound(user2), false); + map.set('user', user2); + assert.equal(canReflect.isBound(user1), false); + assert.equal(canReflect.isBound(user2), true); + }); + QUnit.test('Registering events on nullish context with :by should be supported', function (assert) { + assert.expect(3); + var map = new SimpleMap({ + user: null, + doSomething: function () { + assert.ok(true); + } + }); + var user1 = new SimpleMap({ name: 'Michael' }); + var user2 = new SimpleMap({ name: 'Justin' }); + stache('
      ')(map); + map.set('user', user1); + map.get('user').set('name', 'Greg'); + map.get('user').set('name', 'Jim'); + map.set('user', user2); + map.get('user').set('name', 'Todd'); + }); + QUnit.test('Registering events on nullish context with :by should be supported on :vm bindings', function (assert) { + assert.expect(2); + var map = new SimpleMap({ user: null }); + var ParentScope = SimpleMap.extend({ + doSomething: function () { + assert.ok(true); + } + }); + var parent = new ParentScope(); + var user1 = new SimpleMap({ name: 'Michael' }); + var user2 = new SimpleMap({ name: 'Justin' }); + MockComponent.extend({ + tag: 'view-model-able', + viewModel: map + }); + stache('')(parent); + map.set('user', user1); + map.get('user').set('name', 'Greg'); + map.set('user', user2); + map.get('user').set('name', 'Todd'); + }); + testIfRealDocumentInDev('warning when binding known DOM event name to view model', function (assert) { + var teardown = canTestHelpers.dev.willWarn('The focus event is bound the view model for . Use on:el:focus to bind to the element instead.'); + viewCallbacks.tag('warning-el', function (el) { + el[canSymbol.for('can.viewModel')] = new SimpleMap({}); + }); + var template = stache(''); + var map = new SimpleMap({}); + template(map); + assert.equal(teardown(), 1, 'warning shown'); + }); + QUnit.test('events should not create viewmodels (#540)', function (assert) { + var ta = this.fixture; + var template = stache('
      '); + var frag = template({ + func: function () { + assert.ok(true, 'func ran'); + } + }); + ta.appendChild(frag); + var el = doc.getElementById('click-me'); + domEvents.dispatch(el, 'click'); + assert.equal(el[canSymbol.for('can.viewModel')], undefined, 'el does not have a viewmodel'); + }); + }); +}); +/*can-stache-bindings@4.10.9#test/colon/view-model-test*/ +define('can-stache-bindings@4.10.9#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 (assert) { + var map = new SimpleMap({}); + var MySimpleMap = SimpleMap.extend({ + show: true, + method: function () { + assert.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 (assert) { + 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); + assert.equal(scope.attr('scope1'), 'vm1', 'vm:value:to - scope value set from vm'); + vm1.attr('value', 'vm4'); + assert.equal(scope.attr('scope1'), 'vm4', 'vm:value:to - scope updated when vm changes'); + scope.attr('scope1', 'scope4'); + assert.equal(vm1.attr('value'), 'vm4', 'vm:value:to - vm not updated when scope changes'); + assert.equal(vm2.attr('value'), 'scope2', 'vm:value:from - vm value set from scope'); + scope.attr('scope2', 'scope5'); + assert.equal(vm2.attr('value'), 'scope5', 'vm:value:from - vm updated when scope changes'); + vm2.attr('value', 'vm5'); + assert.equal(scope.attr('scope2'), 'scope5', 'vm:value:from - scope not updated when vm changes'); + assert.equal(vm3.attr('value'), 'scope3', 'vm:value:bind - vm value set from scope'); + scope.attr('scope3', 'scope6'); + assert.equal(vm3.attr('value'), 'scope6', 'vm:value:bind - vm updated when scope changes'); + vm3.attr('value', 'vm6'); + assert.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 (assert) { + var tagName = 'merge-warn-test'; + delete viewCallbacks._tags[tagName]; + assert.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); + assert.deepEqual(data.bar.get(), { 'plonk': 'waldo' }, 'sanity check: parent binding set (default map -> default map)'); + assert.equal(teardown(), 1, 'warning shown'); + }); + QUnit.test('changing a scope property calls registered stache helper\'s returned function', function (assert) { + assert.expect(1); + var done = assert.async(); + var scope = new SimpleMap({ test: 'testval' }); + MockComponent.extend({ + tag: 'test-component', + viewModel: scope, + template: stache('Hello world') + }); + stache.registerHelper('propChangeEventStacheHelper', function () { + return function () { + done(); + assert.ok(true, 'helper\'s returned function called'); + }; + }); + var template = stache(''); + template({}); + scope.set('test', 'changed'); + }); + QUnit.test('one-way pass computes to components with ~', function (assert) { + 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); + assert.ok(vm.get('compute')[canSymbol.for('can.getValue')], 'observable returned'); + assert.equal(vm.get('compute')(), 'bar', 'Compute has correct value'); + canReflect.onValue(vm.get('compute'), function () { + assert.ok(true, 'Change handler called'); + }); + baseVm.set('foo', 'quux'); + assert.equal(vm.get('compute')(), 'quux', 'Compute updates'); + vm.get('compute')('xyzzy'); + assert.equal(baseVm.get('foo'), 'xyzzy', 'Compute does update the other direction'); + }); + QUnit.test('Child bindings updated before parent (#2252)', function (assert) { + 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') { + assert.equal(value, 'view', 'value should not be edit'); + } else { + assert.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(); + }); + QUnit.test('backtrack path in to-parent bindings (#2132)', function (assert) { + MockComponent.extend({ + tag: 'parent-export', + viewModel: { value: 'VALUE' } + }); + var template = stache('{{#innerMap}}{{/innerMap}}'); + var data = new SimpleMap({ innerMap: new SimpleMap({}) }); + template(data); + assert.equal(data.get('parentValue'), 'VALUE', 'set on correct context'); + assert.equal(data.get('innerMap').get('parentValue'), undefined, 'nothing on innerMap'); + }); + QUnit.test('function reference to child binding (#2116)', function (assert) { + assert.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 () { + assert.ok(false, 'should not be called'); + }); + assert.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 () { + assert.ok(false, 'method should not be called'); + }); + assert.equal(typeof vm.get('vmMethod'), 'function', 'parent export function'); + }); + QUnit.test('setter only gets called once (#2117)', function (assert) { + assert.expect(1); + var VM = SimpleMap.extend({ + attr: function (prop, val) { + if (arguments.length > 1 && prop === 'bar') { + assert.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' })); + }); + QUnit.test('function reference to child (#2116)', function (assert) { + assert.expect(2); + var template = stache(''); + MockComponent.extend({ + tag: 'foo-bar', + viewModel: { + method: function () { + assert.ok(false, 'should not be called'); + } + } + }); + var VM = SimpleMap.extend({ + parent: function () { + assert.ok(false, 'should not be called'); + } + }); + var vm = new VM({}); + var frag = template(vm); + assert.equal(typeof canViewModel(frag.firstChild).attr('child'), 'function', 'to child binding'); + template = stache(''); + vm = new VM({}); + template(vm); + assert.ok(typeof vm.attr('vmMethod') === 'function', 'parent export function'); + }); + QUnit.test('exporting methods (#2051)', function (assert) { + assert.expect(2); + MockComponent.extend({ + tag: 'foo-bar', + viewModel: { + method: function () { + assert.ok(true, 'foo called'); + return 5; + } + } + }); + var template = stache('{{scope.vars.refKey()}}'); + var frag = template({}); + assert.equal(frag.lastChild.nodeValue, '5'); + }); + QUnit.test('one way - child to parent - importing viewModel hyphenatedProp:to="test"', function (assert) { + 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); + assert.equal(importPropParentViewModel.get('test'), 'Justin', 'got hyphenated prop'); + assert.equal(importPropParentViewModel.get('childComponent'), canViewModel(importPropScope), 'got view model'); + }); + QUnit.test('one way - child to parent - importing viewModel prop:to="test"', function (assert) { + 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({}); + assert.equal(frag.childNodes.item(0).childNodes.item(1).innerHTML, 'Imported: David', '{name} component scope imported into variable'); + }); + QUnit.test('one-way - child to parent - viewModel', function (assert) { + 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); + assert.equal(viewModel.get('viewModelProp'), 'Mercury', 'initial value kept'); + assert.equal(map.get('scopeProp'), 'Mercury', 'initial value set on parent'); + viewModel.set('viewModelProp', 'Earth'); + assert.equal(map.get('scopeProp'), 'Earth', 'binding from child to parent'); + map.set('scopeProp', 'Mars'); + assert.equal(viewModel.get('viewModelProp'), 'Earth', 'no binding from parent to child'); + }); + QUnit.test('one-way - child to parent - viewModel - with converters', function (assert) { + 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); + assert.equal(viewModel.get('viewModelProp'), 'Mercury', 'initial value kept'); + assert.equal(map.get('scopeProp'), 'MERCURY', 'initial value set on parent, but upper cased'); + viewModel.set('viewModelProp', 'Earth'); + assert.equal(map.get('scopeProp'), 'EARTH', 'binding from child to parent updated'); + map.set('scopeProp', 'Mars'); + assert.equal(viewModel.get('viewModelProp'), 'Earth', 'no binding from parent to child'); + }); + QUnit.test('one-way - parent to child - viewModel', function (assert) { + var template = stache('
      '); + var map = new SimpleMap({ scopeProp: 'Venus' }); + var frag = template(map); + var viewModel = canViewModel(frag.firstChild); + assert.equal(viewModel.attr('viewModelProp'), 'Venus', 'initial value set'); + viewModel.attr('viewModelProp', 'Earth'); + assert.equal(map.attr('scopeProp'), 'Venus', 'no binding from child to parent'); + map.attr('scopeProp', 'Mars'); + assert.equal(viewModel.attr('viewModelProp'), 'Mars', 'binding from parent to child'); + }); + QUnit.test('two-way - reference - child:bind="scope.vars.ref" (#1700)', function (assert) { + 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'); + assert.equal(scope.peek('scope.vars.refName'), 'v1', 'reference scope updated'); + assert.equal(refImport.get('name'), 'v1', 'updated ref-import'); + refImport.set('name', 'v2'); + assert.equal(refExport.get('name'), 'v2', 'updated ref-export'); + assert.equal(scope.peek('scope.vars.refName'), 'v2', 'actually put in refs scope'); + }); + QUnit.test('one-way - DOM - parent value undefined (#189)', function (assert) { + 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; + } + assert.equal(text(button), 'false', 'Initial value is "false"'); + domEvents.dispatch(button, 'click'); + assert.equal(text(button), 'true', 'Value is "true" after first click'); + domEvents.dispatch(button, 'click'); + assert.equal(text(button), 'false', 'Value is "false" after second click'); + }); + QUnit.test('two way - viewModel (#1700)', function (assert) { + 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); + assert.equal(scopeMapSetCalled, 0, 'set is not called on scope map'); + assert.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'); + assert.equal(map.get('scopeProp'), 'HELLO', 'binding from child to parent'); + assert.equal(scopeMapSetCalled, 1, 'set is called on scope map'); + assert.equal(viewModelSetCalled, 2, 'set is called viewModel'); + map.set('scopeProp', 'WORLD'); + assert.equal(viewModel.get('viewModelProp'), 'WORLD', 'binding from parent to child'); + assert.equal(scopeMapSetCalled, 1, 'can.setKey is not called again on scope map'); + assert.equal(viewModelSetCalled, 3, 'set is called again on viewModel'); + }); + QUnit.test('standard attributes should not set viewModel props', function (assert) { + MockComponent.extend({ + tag: 'test-elem', + viewModel: SimpleMap + }); + var template = stache(''); + var frag = template(new SimpleMap({ bar: true })); + var vm = canViewModel(frag.firstChild); + assert.equal(vm.get('foo'), undefined); + }); + QUnit.test('set string on the viewModel', function (assert) { + assert.expect(2); + var ViewModel = DefineMap.extend({ + foo: { + type: 'string', + set: function (val) { + assert.equal(val, 'bar'); + } + }, + baz: { + type: 'string', + set: function (val) { + assert.equal(val, 'qux'); + } + } + }); + MockComponent.extend({ + tag: 'test-elem', + viewModel: ViewModel + }); + var template = stache(''); + template(); + }); + QUnit.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 (assert) { + assert.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 () { + assert.ok(true, 'foo called'); + return 5; + } + } + }); + var template = stache('myTemplate.stache', '{{scope.vars.refKey()}}'); + var frag = template({}); + assert.equal(frag.lastChild.nodeValue, '5'); + assert.equal(teardown(), 2, 'warnings displayed for read and write'); + }); + QUnit.test('bindings.viewModel makeViewModel gets passed the binding state', function (assert) { + var element = document.createElement('bindings-viewmodel'); + element.setAttribute('age:from', 'years'); + stacheBindings.behaviors.viewModel(element, { scope: new Scope({ years: 22 }) }, function (data, hasDataBinding, bindingState) { + assert.equal(bindingState.isSettingOnViewModel, true, 'isSettingOnViewModel called with correct value'); + assert.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) { + assert.ok(!bindingState.isSettingOnViewModel, 'isSettingOnViewModel called with correct value'); + assert.ok(bindingState.isSettingViewModel, 'isSettingOnViewModel called with correct value'); + }, {}); + }); + QUnit.test('double parent update', function (assert) { + 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); + assert.equal(parentVM.get('parentValue'), 'gc'); + }); + QUnit.test('scope.event should be available', function (assert) { + var vm = new SimpleMap({}); + MockComponent.extend({ + tag: 'event-producer', + viewModel: vm, + template: stache('') + }); + var template = stache(''); + template({ + doSomething: function (events, argums, args) { + assert.equal(events.type, 'event', 'got an event'); + assert.equal(argums.length, 2, 'two arguments'); + assert.equal(args.length, 3, '3 args'); + } + }); + vm.dispatch({ type: 'event' }, [ + 1, + 2 + ]); + }); + QUnit.test('nested props with two way binding', function (assert) { + var nestedValue = new SimpleMap({ first: 'Matt' }); + var childVM = new SimpleMap({ name: nestedValue }); + MockComponent.extend({ + tag: 'my-child', + viewModel: childVM, + template: stache('') + }); + var parentVM = new SimpleMap({ name: 'Justin' }); + MockComponent.extend({ + tag: 'my-parent', + viewModel: parentVM, + template: stache('') + }); + var template = stache('')(); + var parentInput = template.childNodes.item(0).childNodes.item(1); + var childInput = template.childNodes.item(0).childNodes.item(0).childNodes.item(0); + parentInput.value = 'updated'; + domEvents.dispatch(parentInput, 'change'); + assert.equal(parentVM.get('name'), 'updated', 'parent vm has correct value'); + assert.equal(nestedValue.get('first'), 'updated', 'child vm has correct value'); + childInput.value = 'child-updated'; + domEvents.dispatch(childInput, 'change'); + assert.equal(parentVM.get('name'), 'child-updated', 'parent vm has correct value'); + assert.equal(nestedValue.get('first'), 'child-updated', 'child vm has correct value'); + }); + canTestHelpers.dev.devOnlyTest('warn when changing the value of a sticky binding child-side (initializing view model)', function (assert) { + assert.expect(2); + var teardown = canTestHelpers.dev.willWarn('can-bind: The child of the sticky two-way binding is changing or converting its value when set. ' + 'Conversions should only be done on the binding parent to preserve synchronization. ' + 'See https://canjs.com/doc/can-stache-bindings.html#StickyBindings for more about sticky bindings', function (text, match) { + if (match) { + assert.ok(true, 'Correct warning generated'); + } + }); + var childVM = new SimpleMap({ name: { first: 'Matt' } }); + MockComponent.extend({ + tag: 'my-child', + viewModel: childVM, + template: stache('') + }); + var parentVM = new SimpleMap({ name: 'Justin' }); + stache('')(parentVM); + assert.equal(teardown(), 1, 'Warning generated only once'); + }); + }); +}); +/*can-stache-bindings@4.10.9#test/colon/hybrid-test*/ +define('can-stache-bindings@4.10.9#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) { + QUnit.test('value:to:on:click and on:click:value:to work (#269)', function (assert) { + 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'); + assert.equal(map.get('theProp'), '22'); + var eventFirstInput = ta.getElementsByTagName('input')[1]; + eventFirstInput.value = '23'; + domEvents.dispatch(eventFirstInput, 'click'); + assert.equal(map.get('theProp'), '23'); + }); + QUnit.test('on:input:value:to works (#289)', function (assert) { + 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'); + assert.equal(scope.get('myProp'), 'wurld', 'Got the value on the scope'); + }); + QUnit.test('on:input:value:to does not initialize values (#289)', function (assert) { + try { + stache('')(); + assert.ok(true, 'renderer was made without error'); + } catch (e) { + assert.ok(false, e.message); + } + }); + QUnit.test('on:input:value:bind should initialize values (#457)', function (assert) { + var frag = stache('')({ foo: 'bar' }); + var input = frag.firstChild; + assert.equal(input.value, 'bar', 'initialized to the parent value'); + }); + }); +}); +/*can-stache-bindings@4.10.9#test/colon/dependencies-test*/ +define('can-stache-bindings@4.10.9#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.10.9#test/colon/tests*/ +define('can-stache-bindings@4.10.9#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.10.9#test/data/tests*/ +define('can-stache-bindings@4.10.9#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.10.9#test/tests*/ +define('can-stache-bindings@4.10.9#test/tests', [ + 'require', + 'exports', + 'module', + './colon/tests', + './data/tests' +], function (require, exports, module) { + require('./colon/tests'); + require('./data/tests'); +}); +/*can-query-logic@1.2.2#src/set*/ +define('can-query-logic@1.2.2#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.2.2#src/set-test*/ +define('can-query-logic@1.2.2#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 (assert) { + assert.deepEqual(set.ownAndMemberValue(1, '1'), { + own: 1, + member: 1 + }, '1 and \'1\''); + assert.deepEqual(set.ownAndMemberValue({ + valueOf: function () { + return null; + } + }, '1'), { + own: null, + member: '1' + }, '{null} and \'1\''); + }); + QUnit.test('.isDefinedAndHasMembers', function (assert) { + assert.equal(set.isDefinedAndHasMembers({}), true); + assert.equal(set.isDefinedAndHasMembers(set.UNIVERSAL), true); + assert.equal(set.isDefinedAndHasMembers(set.UNDEFINABLE), false); + }); +}); +/*can-query-logic@1.2.2#src/helpers*/ +define('can-query-logic@1.2.2#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; + } + }); + }, + getIdentityIndex: function (compare, items, props, startIndex, schema) { + var identity = canReflect.getIdentity(props, schema), starterItem = items[startIndex]; + if (compare(props, starterItem) === 0) { + if (identity === canReflect.getIdentity(starterItem, schema)) { + return startIndex; + } + } + var rightResult = this.getIdentityIndexByDirection(compare, items, props, startIndex + 1, 1, schema), leftResult; + if (rightResult.index) { + return rightResult.index; + } else { + leftResult = this.getIdentityIndexByDirection(compare, items, props, startIndex - 1, -1, schema); + } + if (leftResult.index !== undefined) { + return leftResult.index; + } + return rightResult.lastIndex; + }, + getIdentityIndexByDirection: function (compare, items, props, startIndex, direction, schema) { + var currentIndex = startIndex; + var identity = canReflect.getIdentity(props, schema); + while (currentIndex >= 0 && currentIndex < items.length) { + var currentItem = items[currentIndex]; + var computed = compare(props, currentItem); + if (computed === 0) { + if (identity === canReflect.getIdentity(currentItem, schema)) { + return { index: currentIndex }; + } + } else { + return { lastIndex: currentIndex - direction }; + } + currentIndex = currentIndex + direction; + } + return { lastIndex: currentIndex - direction }; + }, + getIndex: function (compare, items, props, schema) { + 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 === 0) { + return this.getIdentityIndex(compare, items, props, mid, schema); + } else 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.2.2#src/helpers-test*/ +define('can-query-logic@1.2.2#src/helpers-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './helpers', + 'can-reflect' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var helpers = require('./helpers'); + var canReflect = require('can-reflect'); + QUnit.module('can-query-logic/helpers'); + QUnit.test('.getIdentityIndex', function (assert) { + var items = [ + { + id: 1, + name: 'Item 0' + }, + { + id: 2, + name: 'Item 1' + }, + { + id: 3, + name: 'Item 1' + }, + { + id: 4, + name: 'Item 1' + }, + { + id: 5, + name: 'Item 2' + } + ]; + canReflect.eachIndex(items, function (item) { + canReflect.assignSymbols(item, { + 'can.getSchema': function () { + return { + type: 'map', + identity: ['id'], + keys: { + id: Number, + name: String + } + }; + } + }); + }); + var props = { + id: 2, + name: 'Item 1' + }; + canReflect.assignSymbols(props, { + 'can.getSchema': function () { + return { + type: 'map', + identity: ['id'], + keys: { + id: Number, + name: String + } + }; + } + }); + var compare = helpers.sorter('name', {}); + var res = helpers.getIdentityIndex(compare, items, props, 1); + assert.deepEqual(res, 1); + }); + QUnit.test('.getIndex should not sort unchanged items #33', function (assert) { + var items = [ + { + id: 1, + name: 'Item 0' + }, + { + id: 2, + name: 'Item 1' + }, + { + id: 3, + name: 'Item 1' + }, + { + id: 4, + name: 'Item 1' + }, + { + id: 5, + name: 'Item 2' + } + ]; + canReflect.eachIndex(items, function (item) { + canReflect.assignSymbols(item, { + 'can.getSchema': function () { + return { + type: 'map', + identity: ['id'], + keys: { + id: Number, + name: String + } + }; + } + }); + }); + var compare = helpers.sorter('name', {}); + var res1 = helpers.getIndex(compare, items, items[0]); + var res2 = helpers.getIndex(compare, items, items[1]); + var res3 = helpers.getIndex(compare, items, items[2]); + var res4 = helpers.getIndex(compare, items, items[3]); + assert.equal(res1, 0); + assert.equal(res2, 1); + assert.equal(res3, 2); + assert.equal(res4, 3); + }); + QUnit.test('Missed schema on helper.getIndex #45', function (assert) { + var items = [ + { + id: 1, + name: 'Item 0' + }, + { + id: 2, + name: 'Item 1' + }, + { + id: 3, + name: 'Item 2' + }, + { + id: 4, + name: 'Item 3' + }, + { + id: 5, + name: 'Item 4' + } + ]; + var compare = helpers.sorter('name', {}); + var schema = { + keys: {}, + identity: ['id'] + }; + assert.equal(helpers.getIndex(compare, items, { + id: 2, + name: 'Item 1' + }, schema), 1); + }); +}); +/*can-query-logic@1.2.2#src/array-union-intersection-difference*/ +define('can-query-logic@1.2.2#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.2.2#src/types/comparisons-common*/ +define('can-query-logic@1.2.2#src/types/comparisons-common', function (require, exports, module) { + function isMemberThatUsesTestOnValues(value) { + return this.constructor.test(this.values, value); + } + exports.isMemberThatUsesTestOnValues = isMemberThatUsesTestOnValues; +}); +/*can-query-logic@1.2.2#src/types/types*/ +define('can-query-logic@1.2.2#src/types/types', function (require, exports, module) { + module.exports = {}; +}); +/*can-query-logic@1.2.2#src/types/values-not*/ +define('can-query-logic@1.2.2#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; + } + } + }); + NotIdentity.prototype.isMember = function (value) { + if (this.value && typeof this.value.isMember === 'function') { + return !this.value.isMember(value); + } else { + var values = set.ownAndMemberValue(this.value, value); + return values.own !== values.member; + } + }; + module.exports = keysLogic.Not = NotIdentity; +}); +/*can-query-logic@1.2.2#src/types/array-comparisons*/ +define('can-query-logic@1.2.2#src/types/array-comparisons', [ + 'require', + 'exports', + 'module', + './comparisons-common', + '../set', + './values-not' +], function (require, exports, module) { + var common = require('./comparisons-common'); + var set = require('../set'); + var ValuesNot = require('./values-not'); + var comparisons = { + All: function (values) { + this.values = values; + } + }; + comparisons.All.prototype.isMember = common.isMemberThatUsesTestOnValues; + var is = comparisons; + comparisons.All.test = function (allValues, recordValues) { + return allValues.every(function (allValue) { + return recordValues.some(function (recordValue) { + var values = set.ownAndMemberValue(allValue, recordValue); + return values.own === values.member; + }); + }); + }; + function makeThrowCannotCompare(type, left, right) { + return function () { + throw new Error('can-query-logic: Cannot perform ' + type + ' between ' + left + ' and ' + right); + }; + } + function throwComparatorAllTypes(type1, type2) { + return { + union: makeThrowCannotCompare('union', type1, type2), + difference: makeThrowCannotCompare('difference', type1, type2), + intersection: makeThrowCannotCompare('intersection', type1, type2) + }; + } + function throwComparatorDifference(type1, type2) { + return { difference: makeThrowCannotCompare('difference', type1, type2) }; + } + var comparators = { + UNIVERSAL_All: { + difference: function (universe, all) { + return new ValuesNot(all); + } + }, + All_UNIVERSAL: { + difference: function () { + return set.EMPTY; + } + }, + All_All: { + union: function (a, b) { + return new is.Or([ + a, + b + ]); + } + }, + In_All: throwComparatorDifference('In', 'All'), + All_In: throwComparatorAllTypes('All', 'In'), + NotIn_All: throwComparatorDifference('NotIn', 'All'), + All_NotIn: throwComparatorAllTypes('All', 'NotIn'), + GreaterThan_All: throwComparatorDifference('GreaterThan', 'All'), + All_GreaterThan: throwComparatorAllTypes('All', 'GreaterThan'), + GreaterThanEqual_All: throwComparatorDifference('GreaterThanEqual', 'All'), + All_GreaterThanEqual: throwComparatorAllTypes('All', 'GreaterThanEqual'), + LessThan_All: throwComparatorDifference('LessThan', 'All'), + All_LessThan: throwComparatorAllTypes('All', 'LessThan'), + LessThanEqual_All: throwComparatorDifference('LessThanEqual', 'All'), + All_LessThanEqual: throwComparatorAllTypes('All', 'LessThanEqual'), + All_And: throwComparatorDifference('All', 'And'), + And_All: throwComparatorAllTypes('And', 'All'), + All_Or: throwComparatorDifference('All', 'Or'), + Or_All: throwComparatorAllTypes('Or', 'All') + }; + exports.comparisons = comparisons; + exports.comparators = comparators; +}); +/*can-query-logic@1.2.2#src/types/comparisons*/ +define('can-query-logic@1.2.2#src/types/comparisons', [ + 'require', + 'exports', + 'module', + '../set', + '../array-union-intersection-difference', + './comparisons-common', + './array-comparisons', + 'can-reflect', + 'can-symbol' +], function (require, exports, module) { + var set = require('../set'); + var arrayUnionIntersectionDifference = require('../array-union-intersection-difference'); + var common = require('./comparisons-common'); + var arrayComparisons = require('./array-comparisons'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var isMemberSymbol = canSymbol.for('can.isMember'); + var comparisons = canReflect.assign(arrayComparisons.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; + }); + [ + comparisons.In, + comparisons.NotIn + ].forEach(function (Type) { + Type.prototype.isMember = common.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; + }); + var is = comparisons; + 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 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; + }; + } + var isMemberTest = { + test: function isMemberTest(set, value) { + return set.isMember(value); + } + }; + 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 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; + } + 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 = canReflect.assign(arrayComparisons.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.2.2#src/types/make-real-number-range-inclusive*/ +define('can-query-logic@1.2.2#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.2.2#src/types/make-real-number-range-inclusive-test*/ +define('can-query-logic@1.2.2#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 (assert) { + assert.equal(set.isSubset(new RealNumberRangeInclusive(1, 4), new RealNumberRangeInclusive(0, 5)), true, '1-4 subset of 0-5'); + assert.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 (assert) { + assert.equal(set.isEqual(new RealNumberRangeInclusive(1, 4), set.UNIVERSAL), false, 'universal second'); + assert.equal(set.isEqual(set.UNIVERSAL, new RealNumberRangeInclusive(1, 4)), false, 'universal first'); + assert.equal(set.isEqual(new RealNumberRangeInclusive(-Infinity, Infinity), set.UNIVERSAL), true, 'eq universal second'); + assert.equal(set.isEqual(set.UNIVERSAL, new RealNumberRangeInclusive(-Infinity, Infinity)), true, 'eq universal second'); + }); +}); +/*can-query-logic@1.2.2#src/types/comparisons-test*/ +define('can-query-logic@1.2.2#src/types/comparisons-test', [ + 'require', + 'exports', + 'module', + './comparisons', + '../set', + './values-not' +], function (require, exports, module) { + var compare = require('./comparisons'); + var set = require('../set'); + var is = compare; + var ValuesNot = require('./values-not'); + 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); + assert.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 = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]); + var 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'); + } + }, + UNIVERSAL_All: { + difference: function (assert) { + var all = new is.All(['test']); + assert.deepEqual(set.difference(set.UNIVERSAL, all), new ValuesNot(new is.All(['test']))); + } + }, + All_UNIVERSAL: { + difference: function (assert) { + var all = new is.All(['test']); + assert.deepEqual(set.difference(all, set.UNIVERSAL), set.EMPTY); + } + }, + All_All: { + union: function (assert) { + var a = new is.All(['a']); + var b = new is.All(['b']); + assert.deepEqual(set.union(a, b), new is.Or([ + new is.All(['a']), + new is.All(['b']) + ])); + } + }, + In_All: { + union: function (assert) { + var a = new is.In(['a']); + var b = new is.All(['b']); + assert.throws(function () { + set.union(a, b); + }, 'unable to compare'); + }, + difference: function (assert) { + var a = new is.In(['a']); + var b = new is.All(['b']); + assert.throws(function () { + set.union(a, b); + }, 'unable to compare'); + } + }, + All_In: { + union: function (assert) { + var a = new is.In(['a']); + var b = new is.All(['b']); + assert.throws(function () { + set.union(b, a); + }, 'unable to compare'); + }, + difference: function (assert) { + var a = new is.In(['a']); + var b = new is.All(['b']); + assert.throws(function () { + set.difference(b, a); + }, 'unable to compare'); + } + }, + NotIn_All: { + union: function (assert) { + var a = new is.In(['a']); + var b = new is.All(['b']); + assert.throws(function () { + set.union(a, b); + }, 'unable to compare'); + } + }, + All_NotIn: { + union: function (assert) { + var a = new is.In(['a']); + var b = new is.All(['b']); + assert.throws(function () { + set.union(b, a); + }, 'unable to compare'); + } + }, + And_All: { + union: function (assert) { + var a = new is.And([{ a: 'b' }]); + var b = new is.All(['b']); + assert.throws(function () { + set.union(a, b); + }, 'unable to compare'); + }, + difference: function (assert) { + var a = new is.And([{ a: 'b' }]); + var b = new is.All(['b']); + assert.throws(function () { + set.difference(a, b); + }, 'unable to compare'); + }, + intersection: function (assert) { + var a = new is.And([{ a: 'b' }]); + var b = new is.All(['b']); + assert.throws(function () { + set.intersection(a, b); + }, 'unable to compare'); + } + }, + All_Or: { + union: function (assert) { + var a = new is.Or([{ a: 'b' }]); + var b = new is.All(['b']); + assert.throws(function () { + set.union(a, b); + }, 'unable to compare'); + }, + difference: function (assert) { + var a = new is.Or([{ a: 'b' }]); + var b = new is.All(['b']); + assert.throws(function () { + set.difference(a, b); + }, 'unable to compare'); + }, + intersection: function (assert) { + var a = new is.Or([{ a: 'b' }]); + var b = new is.All(['b']); + assert.throws(function () { + set.intersection(a, b); + }, 'unable to compare'); + } + } + }; + 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 (assert) { + 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())); + assert.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); + assert.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())); + assert.deepEqual(difference, new is.And([ + gt1980, + lte1990 + ]), 'difference'); + }); + QUnit.test('Able to do membership, union, difference with $in', function (assert) { + 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) + ]); + assert.ok(in80or90.isMember(date1980), 'is member'); + var in90or00 = new compare.In([ + new DateStrSet(date1990), + new DateStrSet(date2000) + ]); + var union = set.union(in80or90, in90or00); + assert.deepEqual(union, new compare.In([ + new DateStrSet(date1980), + new DateStrSet(date1990), + new DateStrSet(date2000) + ]), 'union'); + }); + QUnit.test('All on arrays', function (assert) { + var arrayHasAbc = new is.All(['abc']); + assert.equal(arrayHasAbc.isMember(['abc']), true); + assert.equal(arrayHasAbc.isMember([ + 'abc', + 'def' + ]), true); + assert.equal(arrayHasAbc.isMember(['def']), false); + assert.equal(arrayHasAbc.isMember([]), false); + var hasAbcAndDef = new is.And([ + new is.All(['abc']), + new is.All(['def']) + ]); + assert.equal(hasAbcAndDef.isMember(['abc']), false); + assert.equal(hasAbcAndDef.isMember([ + 'abc', + 'def' + ]), true); + assert.equal(hasAbcAndDef.isMember(['def']), false); + assert.equal(hasAbcAndDef.isMember([]), false); + var hasAbcAndNotDef = new is.And([ + new is.All(['abc']), + new ValuesNot(new is.All(['def'])) + ]); + assert.equal(hasAbcAndNotDef.isMember(['abc']), true); + assert.equal(hasAbcAndNotDef.isMember([ + 'abc', + 'def' + ]), false); + assert.equal(hasAbcAndNotDef.isMember(['def']), false); + assert.equal(hasAbcAndNotDef.isMember([]), false); + }); +}); +/*can-query-logic@1.2.2#src/types/values-or*/ +define('can-query-logic@1.2.2#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.2.2#src/types/values-and*/ +define('can-query-logic@1.2.2#src/types/values-and', [ + 'require', + 'exports', + 'module', + './types', + '../set' +], function (require, exports, module) { + var keysLogic = require('./types'); + var set = require('../set'); + function ValuesAnd(values) { + this.values = values; + } + ValuesAnd.prototype.isMember = function (props) { + return this.values.every(function (value) { + return value && value.isMember ? value.isMember(props) : value === props; + }); + }; + set.defineComparison(set.UNIVERSAL, ValuesAnd, { + difference: function () { + return set.UNDEFINABLE; + } + }); + module.exports = keysLogic.ValuesAnd = ValuesAnd; +}); +/*can-query-logic@1.2.2#src/types/keys-and*/ +define('can-query-logic@1.2.2#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.2.2#src/types/and-or-not*/ +define('can-query-logic@1.2.2#src/types/and-or-not', [ + 'require', + 'exports', + 'module', + './values-or', + './values-not', + './values-and', + './keys-and' +], function (require, exports, module) { + var ValuesOr = require('./values-or'); + var ValuesNot = require('./values-not'); + var ValuesAnd = require('./values-and'); + var KeysAnd = require('./keys-and'); + module.exports = { + KeysAnd: KeysAnd, + ValuesOr: ValuesOr, + ValuesNot: ValuesNot, + ValuesAnd: ValuesAnd + }; +}); +/*can-query-logic@1.2.2#src/schema-helpers*/ +define('can-query-logic@1.2.2#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.2.2#src/types/make-enum*/ +define('can-query-logic@1.2.2#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.2.2#src/types/and-or-not-test*/ +define('can-query-logic@1.2.2#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 (assert) { + var AndObject = types.KeysAnd; + var isJustin = new AndObject({ name: 'Justin' }); + var is35 = new AndObject({ age: 35 }); + var is35AndJustin = set.intersection(is35, isJustin); + assert.deepEqual(is35AndJustin.values, { + name: 'Justin', + age: 35 + }, '35 and justin'); + var isJustinAnd35 = set.intersection(isJustin, is35); + assert.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); + assert.equal(is34and35, set.EMPTY, 'can\'t be 34 and 35'); + }); + QUnit.test('AND union basics', function (assert) { + var AndObject = types.KeysAnd; + var isJustin = new AndObject({ name: 'Justin' }); + var is35 = new AndObject({ age: 35 }); + var is35OrJustin = set.union(is35, isJustin); + assert.deepEqual(is35OrJustin, new types.ValuesOr([ + is35, + isJustin + ]), '35 and justin'); + }); + QUnit.test('AND / OR / NOT union', function (assert) { + var isJustin = new types.KeysAnd({ name: 'Justin' }), isNotJustin = new types.KeysAnd({ name: new types.ValuesNot('Justin') }); + assert.equal(set.union(isJustin, isNotJustin), set.UNIVERSAL, '{name: \'j\'} U {name: NOT(\'j\')}'); + var everything = new types.KeysAnd({}); + assert.equal(set.union(isJustin, everything), set.UNIVERSAL, '{name: \'j\'} U {}'); + var isJustinAnd21 = new types.KeysAnd({ + name: 'Justin', + age: 22 + }); + assert.equal(set.union(isJustin, isJustinAnd21), isJustin, 'super and subset'); + assert.equal(set.union(isJustinAnd21, isJustinAnd21), isJustinAnd21, 'union with itself'); + }); + QUnit.test('AND / OR / NOT difference', function (assert) { + 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); + assert.deepEqual(result, isJustinAndNot35, 'OVERLAP: {name: "Justin"} \\ {age: 35} -> {name: "justin", age: NOT(35)}'); + assert.deepEqual(set.difference(is35, is35), set.EMPTY, 'SAME SET: {age: 35} \\ {age: 35} -> EMPTY'); + assert.deepEqual(set.difference(isJustinAnd35, is35), set.EMPTY, 'SUPERSET: {age: 35, name: "Justin"} \\ {age: 35} -> EMPTY'); + assert.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 })); + assert.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); + assert.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); + assert.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) }) + ]); + assert.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 + })); + assert.deepEqual(result, set.EMPTY, 'UNIVESAL: {foo:2} {foo:2, bar: IS_UNIVERSAL} -> set.EMPTY'); + }); + QUnit.test('AND / OR / NOT isSubset', function (assert) { + var res; + res = set.isSubset(new types.KeysAnd({ type: 'FOLDER' }), new types.KeysAnd({ type: 'FOLDER' })); + assert.ok(res, 'equal sets'); + res = set.isSubset(new types.KeysAnd({ + type: 'FOLDER', + parentId: 5 + }), new types.KeysAnd({ type: 'FOLDER' })); + assert.ok(res, 'sub set'); + res = set.isSubset(new types.KeysAnd({ type: 'FOLDER' }), new types.KeysAnd({ + type: 'FOLDER', + parentId: 5 + })); + assert.notOk(res, 'wrong way'); + res = set.isSubset(new types.KeysAnd({ + type: 'FOLDER', + parentId: 7 + }), new types.KeysAnd({ + type: 'FOLDER', + parentId: 5 + })); + assert.ok(!res, 'different values'); + }); + QUnit.test('union AND with ENUM', function (assert) { + 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); + assert.deepEqual(res, new types.KeysAnd({ + type: 'FOLDER', + status: new ColorSet([ + 'red', + 'green' + ]) + }), 'able to do a union'); + }); + QUnit.test('AND isMember', function (assert) { + var folderAnd35 = new types.KeysAnd({ + type: 'FOLDER', + age: 35 + }); + assert.ok(folderAnd35.isMember({ + type: 'FOLDER', + age: 35 + })); + assert.ok(folderAnd35.isMember({ + type: 'FOLDER', + age: 35, + extra: 'value' + })); + assert.notOk(folderAnd35.isMember({ + type: 'FOLDER', + age: 36 + })); + assert.notOk(folderAnd35.isMember({ + type: 'folder', + age: 35 + })); + assert.notOk(folderAnd35.isMember({ type: 'FOLDER' })); + assert.notOk(folderAnd35.isMember({ age: 35 })); + var isJustinPostCollege = new types.KeysAnd({ + name: { first: 'Justin' }, + age: 33 + }); + assert.ok(isJustinPostCollege.isMember({ + name: { + first: 'Justin', + last: 'Meyer' + }, + age: 33 + }), 'is member'); + }); + QUnit.test('OR isMember', function (assert) { + var isFolder = new types.KeysAnd({ type: 'FOLDER' }), is35 = new types.KeysAnd({ age: 35 }), isFolderOr35 = new types.ValuesOr([ + isFolder, + is35 + ]); + assert.ok(isFolderOr35.isMember({ + type: 'FOLDER', + age: 35 + }), 'both'); + assert.notOk(isFolderOr35.isMember({}), 'empty'); + assert.ok(isFolderOr35.isMember({ + type: 'FOLDER', + age: 36 + })); + assert.ok(isFolderOr35.isMember({ + type: 'folder', + age: 35 + })); + assert.notOk(isFolderOr35.isMember({ + type: 'folder', + age: 36 + })); + assert.ok(isFolderOr35.isMember({ type: 'FOLDER' })); + assert.ok(isFolderOr35.isMember({ age: 35 })); + }); + QUnit.test('And nested objects', function (assert) { + var res; + var isNameFirstJustin = new types.KeysAnd({ name: { first: 'Justin' } }); + var isNameFirstJustin2 = new types.KeysAnd({ name: { first: 'Justin' } }); + res = set.isEqual(isNameFirstJustin, isNameFirstJustin2); + assert.equal(res, true); + }); + QUnit.module('can-query-logic/not'); + QUnit.test('union basics', function (assert) { + assert.equal(set.union(new types.ValuesNot(1), 1), set.UNIVERSAL, 'is univesal set'); + }); + QUnit.test('difference with universal', function (assert) { + assert.equal(set.difference(new types.ValuesNot(1), set.UNIVERSAL), set.EMPTY, 'not 1 \\ univesal = 1'); + assert.deepEqual(set.difference(set.UNIVERSAL, 1), new types.ValuesNot(1), '1 \\ univesal = not 1'); + }); + QUnit.test('And with nested.properties', function (assert) { + assert.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'); + assert.equal(new types.KeysAnd({ + 'name.first': 'Justin', + 'name.last': 'Meyer' + }).isMember({ + name: { + first: 'Justin', + last: 'Meyer' + } + }), true, 'dot.ed properties isMember match'); + assert.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 (assert) { + assert.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'); + assert.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'); + assert.equal(new types.KeysAnd({ + name: new types.KeysAnd({ + first: 'Justin', + last: 'Meyer' + }) + }).isMember({ + name: { + first: 'Justin', + last: 'Meyer' + } + }), true, 'dot.ed properties isMember match'); + assert.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 (assert) { + 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); + assert.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); + assert.deepEqual(result, b); + }); +}); +/*can-query-logic@1.2.2#src/types/values-or-test*/ +define('can-query-logic@1.2.2#src/types/values-or-test', [ + 'module', + '@loader', + 'require' +], function (module, loader, require) { + loader.get('@@global-helpers').prepareGlobal({ + require: require, + name: module.id, + deps: [] + }); + var define = loader.global.define; + var require = loader.global.require; + var source = ''; + 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, undefined); +}); +/*can-query-logic@1.2.2#src/types/basic-query*/ +define('can-query-logic@1.2.2#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' +], 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 KeysAnd = andOrNot.KeysAnd, Or = andOrNot.ValuesOr, Not = andOrNot.ValuesNot, And = andOrNot.ValuesAnd; + var RecordRange = makeRealNumberRangeInclusive(0, Infinity); + function makeSort(schema, hydrateAndValue) { + var schemaKeys = schema.keys; + 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); + var $eq = hydrateAndValue({ $eq: valueA }, key, schemaProp, helpers.valueHydrator); + return set.isEqual(set.union($gt, $eq), $gt); + }, + $lt: function (valueA, valueB) { + if (valueA == null || valueB == null) { + return helpers.typeCompare.$lt(valueA, valueB); + } + var $lt = hydrateAndValue({ $lt: valueB }, key, schemaProp, helpers.valueHydrator); + var $eq = hydrateAndValue({ $eq: valueA }, key, schemaProp, helpers.valueHydrator); + return set.isEqual(set.union($lt, $eq), $lt); + } + }; + }); + function Sort(key) { + this.key = key; + this.schema = schema; + 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({ + keys: {}, + identity: ['id'] + }); + 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.And = And; + 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) { + var parentIsUniversal; + if (parentQuery) { + parentIsUniversal = set.isEqual(parentQuery.page, set.UNIVERSAL); + if (parentIsUniversal && !set.isEqual(parentQuery.filter, set.UNIVERSAL) && !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); + if (parentIsUniversal == null) { + 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, this.sort.schema); + }, + 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; + } + } + break; + 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.2.2#src/types/basic-query-test*/ +define('can-query-logic@1.2.2#src/types/basic-query-test', [ + 'require', + 'exports', + 'module', + './basic-query', + 'steal-qunit', + './keys-and', + './values-and' +], function (require, exports, module) { + var BasicQuery = require('./basic-query'); + var QUnit = require('steal-qunit'); + var KeysAnd = require('./keys-and'); + var ValuesAnd = require('./values-and'); + QUnit.module('can-query-logic/types/basic-query filterMembersAndGetCount'); + QUnit.test('Able to filter on a universal set', function (assert) { + var parent = new BasicQuery({ filter: new KeysAnd({}) }); + var bData = [ + {}, + {} + ]; + var FooType = function (value) { + this.value = value; + }; + FooType.prototype.isMember = function () { + return true; + }; + var root = new BasicQuery({ filter: new ValuesAnd([new FooType()]) }); + var res = root.filterMembersAndGetCount(bData, parent); + assert.equal(res.count, 2, 'got all members'); + }); + QUnit.test('Page is a universal set', function (assert) { + var parent = new BasicQuery({ filter: new KeysAnd({}) }); + var bData = [ + {}, + {} + ]; + var FooType = function (value) { + this.value = value; + }; + FooType.prototype.isMember = function () { + return true; + }; + var root = new BasicQuery({ + filter: new ValuesAnd([new FooType()]), + page: new BasicQuery.RecordRange(1, 2) + }); + var res = root.filterMembersAndGetCount(bData, parent); + assert.equal(res.count, 2, 'got all members'); + }); +}); +/*can-query-logic@1.2.2#src/types/basic-query-sorting-test*/ +define('can-query-logic@1.2.2#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); + } + QUnit.test('rangeInclusive legacyDifference', function (assert) { + var res = legacyDifference({ + start: 0, + end: 99 + }, { + start: 50, + end: 101 + }); + assert.deepEqual(res, { + start: 0, + end: 49 + }, 'got a diff'); + res = legacyDifference({}, { + start: 0, + end: 10 + }); + assert.deepEqual(res, { + start: 11, + end: Infinity + }, 'universal set'); + res = legacyDifference({ + start: 0, + end: 49 + }, { + start: 50, + end: 101 + }); + assert.deepEqual(res, { + start: 0, + end: 49 + }, 'side by side'); + res = legacyDifference({ + start: 0, + end: 49 + }, { + start: 0, + end: 20 + }); + assert.deepEqual(res, { + start: 21, + end: 49 + }, 'first set extends past second'); + res = legacyDifference({ + start: 0, + end: 49 + }, { + start: 20, + end: 49 + }); + assert.deepEqual(res, { + start: 0, + end: 19 + }, 'first set starts before second'); + }); + QUnit.test('rangeInclusive legacyIntersection', function (assert) { + var res = legacyIntersection({ + start: 0, + end: 99 + }, { + start: 50, + end: 101 + }); + assert.deepEqual(res, { + start: 50, + end: 99 + }, 'got a intersection'); + }); + QUnit.test('rangeInclusive legacyIsEqual', function (assert) { + assert.ok(!legacyIsEqual({ + start: 0, + end: 100 + }, { + start: 0, + end: 101 + }), 'they are not equal'); + assert.ok(!legacyIsEqual({ + start: 0, + end: 100 + }, { + start: 1, + end: 100 + }), 'they are not equal'); + }); + QUnit.test('rangeInclusive legacySubset', function (assert) { + assert.ok(legacySubset({ + start: 0, + end: 100 + }, { + start: 0, + end: 100 + }), 'self is a subset'); + assert.ok(legacySubset({ + start: 0, + end: 100 + }, { + start: 0, + end: 101 + }), 'end extends past subset'); + assert.equal(legacySubset({ + start: 0, + end: 101 + }, { + start: 0, + end: 100 + }), false, 'non-subset extends past end'); + assert.ok(legacySubset({ + start: 1, + end: 100 + }, { + start: 0, + end: 100 + }), 'start extends before subset'); + assert.ok(!legacySubset({ + start: 0, + end: 100 + }, { + start: 1, + end: 100 + }), 'non-subset extends before start'); + }); + QUnit.test('rangeInclusive legacyUnion', function (assert) { + var res = legacyUnion({}, { + start: 0, + end: 10 + }); + assert.deepEqual(res, {}, 'universal set'); + res = legacyUnion({ + start: 100, + end: 199 + }, { + start: 200, + end: 299 + }); + assert.deepEqual(res, { + start: 100, + end: 299 + }, 'no intersection'); + res = legacyUnion({ + start: 200, + end: 299 + }, { + start: 100, + end: 199 + }); + assert.deepEqual(res, { + start: 100, + end: 299 + }, 'no intersection with either argument order'); + res = legacyUnion({ + start: 200, + end: 299 + }, { + start: 100, + end: 209 + }); + assert.deepEqual(res, { + start: 100, + end: 299 + }, 'sets can intersect'); + res = legacyUnion({ + start: 100, + end: 209 + }, { + start: 200, + end: 299 + }); + assert.deepEqual(res, { + start: 100, + end: 299 + }, 'sets can intersect with either argument order'); + res = legacyUnion({ + start: 100, + end: 299 + }, { + start: 103, + end: 209 + }); + assert.deepEqual(res, { + start: 100, + end: 299 + }, 'first set contains second'); + res = legacyUnion({ + start: 100, + end: 299 + }, { + start: 103, + end: 209 + }); + assert.deepEqual(res, { + start: 100, + end: 299 + }, 'second set contains first'); + res = legacyUnion({ + start: 100, + end: 299 + }, { + start: 100, + end: 299 + }); + assert.deepEqual(res, { + start: 100, + end: 299 + }, 'union of identical sets is the same as those sets'); + }); + QUnit.test('rangeInclusive set.count', function (assert) { + var query = new BasicQuery({ + page: new BasicQuery.RecordRange(0, 99), + filter: set.UNIVERSAL + }); + var res = query.count({ + start: 0, + end: 99 + }); + assert.equal(res, 100, 'count is right'); + }); + QUnit.test('index uses can-reflect', function (assert) { + 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 + ]); + assert.equal(res, 1, 'inserted at 1'); + assert.deepEqual([ + obj1Read, + obj2Read, + itemKeyRead, + itemOwnKeyRead + ], [ + true, + true, + true, + true + ], 'read everything'); + }); + QUnit.test('.index should work with literal objects', function (assert) { + var query = new BasicQuery({ sort: 'name' }); + var items = [ + { + id: 1, + name: 'Item 0' + }, + { + id: 2, + name: 'Item 1' + } + ]; + var res = query.index({ + id: 1, + name: 'Item 1' + }, items); + assert.equal(res, 1, 'Item index at 1'); + }); +}); +/*can-query-logic@1.2.2#src/types/basic-query-filter-from-test*/ +define('can-query-logic@1.2.2#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 (assert) { + var query = new BasicQuery({ + filter: new BasicQuery.KeysAnd({ type: 'critical' }), + page: new BasicQuery.RecordRange(1, 3) + }); + var res = query.filterFrom(items); + assert.deepEqual(res && res.map(getId), [ + 2, + 4, + 6 + ]); + }); + QUnit.test('ordered ascending and paginated', function (assert) { + var query = new BasicQuery({ + filter: new BasicQuery.KeysAnd({ type: 'critical' }), + page: new BasicQuery.RecordRange(1, 3), + sort: 'note' + }); + var res = query.filterFrom(items); + assert.deepEqual(res && res.map(getId), [ + 7, + 1, + 2 + ]); + }); + QUnit.test('ordered descending and paginated', function (assert) { + var query = new BasicQuery({ + filter: new BasicQuery.KeysAnd({ type: 'critical' }), + page: new BasicQuery.RecordRange(1, 3), + sort: '-note' + }); + var res = query.filterFrom(items); + assert.deepEqual(res && res.map(getId), [ + 2, + 1, + 7 + ]); + }); + QUnit.test('against paginated set', function (assert) { + 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); + assert.deepEqual(res && res.map(getId), [ + 2, + 4, + 6 + ]); + }); + QUnit.test('returns undefined against incompatible set', function (assert) { + var query = new BasicQuery({ filter: new BasicQuery.KeysAnd({ note: 'C' }) }); + var fromQuery = new BasicQuery({ filter: new BasicQuery.KeysAnd({ type: 'critical' }) }); + var res; + try { + res = query.filterFrom(items, fromQuery); + } catch (e) { + assert.ok(true, 'throws an error'); + } + assert.notOk(res, 'did not throw an error'); + }); +}); +/*can-query-logic@1.2.2#src/types/basic-query-merge-test*/ +define('can-query-logic@1.2.2#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 (assert) { + var fooBar = new BasicQuery({ filter: new BasicQuery.KeysAnd({ foo: 'bar' }) }); + var res = everything.merge(fooBar, items, items.slice(0, 3), getId); + assert.deepEqual(res, items); + }); + QUnit.test('unionMembers against ranged sets', function (assert) { + 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); + assert.deepEqual(union, items, 'disjoint after'); + }); + QUnit.test('unionMembers against overlapping ranged sets', function (assert) { + 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); + assert.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); + assert.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); + assert.deepEqual(union, items); + }); + QUnit.test('unionMembers filters for uniqueness', function (assert) { + 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); + assert.deepEqual(union, unionItems); + union = b.merge(a, bItems, aItems, getId); + assert.deepEqual(union, unionItems); + }); +}); +/*can-query-logic@1.2.2#src/serializer*/ +define('can-query-logic@1.2.2#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.2.2#src/serializers/comparisons*/ +define('can-query-logic@1.2.2#src/serializers/comparisons', [ + 'require', + 'exports', + 'module', + '../types/comparisons', + '../serializer', + 'can-reflect', + '../types/values-not' +], function (require, exports, module) { + var is = require('../types/comparisons'); + var Serializer = require('../serializer'); + var canReflect = require('can-reflect'); + var ValuesNot = require('../types/values-not'); + 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('$all', makeNew(is.All)); + var oppositeTypeMap = { + LessThan: { + Type: is.GreaterThanEqual, + prop: 'value' + }, + LessThanEqual: { + Type: is.GreaterThan, + prop: 'value' + }, + GreaterThan: { + Type: is.LessThanEqual, + prop: 'value' + }, + GreaterThanEqual: { + Type: is.LessThan, + prop: 'value' + }, + In: { + Type: is.NotIn, + prop: 'values' + }, + NotIn: { + Type: is.In, + prop: 'values' + } + }; + hydrateMap.$not = function (value, unknownHydrator) { + var hydratedValue = hydrateValue(value.$not, unknownHydrator); + var typeName = hydratedValue.constructor.name || hydratedValue.constructor.toString().match(/^\s*function\s*(\S*)\s*\(/)[1]; + if (oppositeTypeMap[typeName]) { + var options = oppositeTypeMap[typeName]; + var OppositeConstructor = options.Type; + var prop = options.prop; + return new OppositeConstructor(hydratedValue[prop]); + } + return new ValuesNot(hydratedValue); + }; + addHydrateFromValues('$nin', makeNew(is.NotIn)); + 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; + } + ], + [ + is.All, + function (all, serialize) { + return { $all: serialize(all.values) }; + } + ] + ]); + function hydrateValue(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)]); + } + } + module.exports = { + hydrate: hydrateValue, + serializer: serializer + }; +}); +/*can-query-logic@1.2.2#src/types/make-maybe*/ +define('can-query-logic@1.2.2#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.2.2#src/serializers/basic-query*/ +define('can-query-logic@1.2.2#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) { + var valuesIsObject = values && typeof values === 'object'; + if (valuesIsObject && '$or' in values) { + return hydrateOrs(values.$or, schemaProperties, hydrateUnknown); + } else if (valuesIsObject && '$and' in values) { + return hydrateAnds(values.$and, 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 hydrateAnds(values, schemaProperties, hydrateUnknown) { + var comparisons = values.map(function (value) { + return hydrateAndValues(value, schemaProperties, hydrateUnknown); + }); + return new BasicQuery.And(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.And, + function (and, serializer) { + return { + $and: and.values.map(function (value) { + return serializer(value); + }) + }; + } + ], + [ + BasicQuery.Not, + function (nots, serializer) { + return { $not: serializer(nots.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(schema, 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.2.2#src/serializers/basic-query-test*/ +define('can-query-logic@1.2.2#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', + '../types/values-and' +], 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'); + var ValuesAnd = require('../types/values-and'); + QUnit.module('can-query-logic/serializers/basic-query'); + var EmptySchema = { + kind: 'record', + identity: ['id'], + keys: {} + }; + QUnit.test('basics', function (assert) { + var query = { filter: { foo: 'bar' } }; + var converter = makeBasicQueryConvert(EmptySchema); + var basicQuery = converter.hydrate(query); + var returnedQuery = converter.serializer.serialize(basicQuery); + assert.deepEqual(returnedQuery, query, 'got back what we give'); + }); + QUnit.test('nested properties', function (assert) { + var query = { filter: { name: { first: 'justin' } } }; + var converter = makeBasicQueryConvert(EmptySchema); + var basicQuery = converter.hydrate(query); + assert.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 (assert) { + 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); + assert.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); + assert.deepEqual(res, { + filter: { + $or: [ + { + foo: 'bar', + age: { $gt: 3 } + }, + { + foo: 'bar', + age: null + } + ] + } + }, 'serialized'); + }); + QUnit.test('auto-convert or schema into maybe type', function (assert) { + 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); + assert.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 (assert) { + assert.expect(3); + var message = 'can-query-logic: Ignoring keys: start, end.'; + var finishErrorCheck = testHelpers.dev.willWarn(message, function (actualMessage, success) { + assert.equal(actualMessage, message, 'Warning is expected message'); + assert.ok(success); + }); + var query = { + filter: { name: { first: 'justin' } }, + start: 0, + end: 1 + }; + var converter = makeBasicQueryConvert(EmptySchema); + converter.hydrate(query); + assert.equal(finishErrorCheck(), 1); + }); + QUnit.test('gt and lt', function (assert) { + var query = { + filter: { + age: { + $gt: 0, + $lt: 100 + } + } + }; + var converter = makeBasicQueryConvert(EmptySchema); + var basicQuery = converter.hydrate(query); + assert.deepEqual(basicQuery.filter, new logicTypes.KeysAnd({ + age: new is.And([ + new is.GreaterThan(0), + new is.LessThan(100) + ]) + })); + var res = converter.serializer.serialize(basicQuery); + assert.deepEqual(res, { + filter: { + age: { + $gt: 0, + $lt: 100 + } + } + }); + }); + QUnit.test('basicquery with no sort', function (assert) { + 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); + assert.equal(res, 1, 'inserted at 1'); + }); + QUnit.test('Complex queries with nested $not, $all', function (assert) { + var query = { + filter: { + $and: [ + { tags: { $all: ['sbux'] } }, + { tags: { $not: { $all: ['dfw'] } } } + ] + } + }; + var converter = makeBasicQueryConvert(EmptySchema); + var basicQuery = converter.hydrate(query); + assert.ok(basicQuery.filter instanceof ValuesAnd); + var res = converter.serializer.serialize(basicQuery); + assert.deepEqual(res, query); + }); + QUnit.test('Inverting $not comparisons', function (assert) { + [ + { + query: { filter: { age: { $not: { $lt: 5 } } } }, + expectedInstance: is.GreaterThanEqual, + expectedValue: 5 + }, + { + query: { filter: { age: { $not: { $lte: 5 } } } }, + expectedInstance: is.GreaterThan, + expectedValue: 5 + }, + { + query: { filter: { age: { $not: { $gt: 5 } } } }, + expectedInstance: is.LessThanEqual, + expectedValue: 5 + }, + { + query: { filter: { age: { $not: { $gte: 5 } } } }, + expectedInstance: is.LessThan, + expectedValue: 5 + }, + { + query: { + filter: { + age: { + $not: { + $in: [ + 2, + 3 + ] + } + } + } + }, + expectedInstance: is.NotIn, + expectedValue: [ + 2, + 3 + ], + valueProp: 'values' + }, + { + query: { + filter: { + age: { + $not: { + $nin: [ + 2, + 3 + ] + } + } + } + }, + expectedInstance: is.In, + expectedValue: [ + 2, + 3 + ], + valueProp: 'values' + } + ].forEach(function (options) { + var query = options.query; + var ExpectedInstance = options.expectedInstance; + var expectedValue = options.expectedValue; + var prop = options.valueProp || 'value'; + var converter = makeBasicQueryConvert(EmptySchema); + var basicQuery = converter.hydrate(query); + assert.ok(basicQuery.filter.values.age instanceof ExpectedInstance, 'changed to right instance type'); + assert.deepEqual(basicQuery.filter.values.age[prop], expectedValue, 'has the correct value'); + }); + }); +}); +/*can-query-logic@1.2.2#src/serializers/comparisons-test*/ +define('can-query-logic@1.2.2#src/serializers/comparisons-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './comparisons', + 'can-reflect', + '../types/values-not' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var comparisons = require('./comparisons'); + var canReflect = require('can-reflect'); + var ValuesNot = require('../types/values-not'); + QUnit.module('can-query-logic/serializers/comparisons'); + QUnit.test('hydrate and serialize with custom types that work with operators', function (assert) { + 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); + }); + assert.deepEqual(hydrated.values, [ + new Type(1), + new Type(2) + ], 'hydrated'); + var serialized = comparisons.serializer.serialize(hydrated); + assert.deepEqual(serialized, { + $in: [ + 1, + 2 + ] + }, 'serialized'); + }); + QUnit.test('unknown hydrator is called in all cases', function (assert) { + var hydrated = []; + var addToHydrated = function (value) { + hydrated.push(value); + }; + comparisons.hydrate({ + $in: [ + 1, + 2 + ] + }, addToHydrated); + comparisons.hydrate('abc', addToHydrated); + comparisons.hydrate([ + 'x', + 'y' + ], addToHydrated); + assert.deepEqual(hydrated, [ + 1, + 2, + 'abc', + 'x', + 'y' + ], 'hydrated called with the right stuff'); + }); + QUnit.test('$not and $all can work recursively', function (assert) { + var hydrated = comparisons.hydrate({ $not: { $all: ['def'] } }, function (value) { + return value; + }); + assert.ok(hydrated instanceof ValuesNot, 'is an instance'); + }); +}); +/*can-query-logic@1.2.2#src/types/make-maybe-test*/ +define('can-query-logic@1.2.2#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('constructor normalizes', function (assert) { + var isNull_3 = new MaybeDateStringSet({ + range: new is.In([ + null, + 3 + ]) + }); + assert.deepEqual(isNull_3.range, new is.In([3]), '3 left in range'); + assert.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) + ]) + }); + assert.deepEqual(isNull_3AsDateString.range, new is.In([new DateStringSet(3)]), '3 left in range'); + assert.deepEqual(isNull_3AsDateString.enum, new is.In([new DateStringSet(null)]), 'range moved to in'); + var isNull = new MaybeDateStringSet({ range: new is.In([null]) }); + assert.deepEqual(isNull.range, set.EMPTY, 'empty if only null'); + assert.deepEqual(isNull.enum, new is.In([null]), 'range moved to in'); + var res = new MaybeDateStringSet({ + range: new is.NotIn([ + null, + 3 + ]) + }); + assert.deepEqual(res.range, new is.NotIn([3]), 'not in range'); + assert.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) + ]) + }); + assert.deepEqual(res.range, new is.GreaterThan(4), 'And with not in'); + assert.deepEqual(res.enum, set.EMPTY, 'And with not in'); + }); + QUnit.test('difference with universal', function (assert) { + var res; + var gt3 = new MaybeDateStringSet({ range: new is.GreaterThan(3) }); + res = set.difference(set.UNIVERSAL, gt3); + assert.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]) })); + assert.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]) })); + assert.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) + })); + assert.deepEqual(res, gt3, 'secondary and primary'); + }); + QUnit.test('difference', function (assert) { + 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) })); + assert.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]) + })); + assert.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) })); + assert.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]) })); + assert.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) + })); + assert.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 + })); + assert.equal(res, set.EMPTY, 'equal is empty'); + }); + QUnit.test('difference with ComparisonSet', function (assert) { + 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) })); + assert.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]) + })); + assert.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) })); + assert.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]) })); + assert.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) + })); + assert.deepEqual(res, gt3, 'secondary and primary'); + }); + QUnit.test('intersection', function (assert) { + 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 + ]) + })); + assert.deepEqual(res, new MaybeDateStringSet({ + range: new is.GreaterThan(5), + enum: new is.In([null]) + }), 'got the right thing'); + }); + QUnit.test('union', function (assert) { + 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]) + })); + assert.deepEqual(res, new MaybeDateStringSet({ + range: new is.GreaterThan(3), + enum: new is.In([ + null, + undefined + ]) + }), 'got the right thing'); + }); + QUnit.test('isSubset', function (assert) { + 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 + })); + assert.ok(res, 'is a subset'); + }); + QUnit.test('can make maybe type from normal type and makeMaybeSetType', function (assert) { + 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 + ] + }; + } + }); + assert.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); + assert.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 (assert) { + 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 + }); + assert.ok(makeMaybe.canMakeMaybeSetType(MaybeDate), 'got everything we need'); + var types = makeMaybe.makeMaybeSetTypes(MaybeDate); + assert.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); + assert.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 (assert) { + var res = new MaybeDateStringSet({ + range: new is.In([3]), + enum: set.EMPTY + }); + assert.deepEqual(res.orValues(), [new is.In([3])], 'only got range'); + res = new MaybeDateStringSet({ + range: set.EMPTY, + enum: new is.In([null]) + }); + assert.deepEqual(res.orValues(), [new is.In([null])], 'only got enum'); + }); +}); +/*can-query-logic@1.2.2#src/types/make-enum-test*/ +define('can-query-logic@1.2.2#src/types/make-enum-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './make-enum', + 'can-symbol' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var makeEnum = require('./make-enum'); + var canSymbol = require('can-symbol'); + QUnit.module('can-query-logic/types/make-enum'); + QUnit.test('.isMember', function (assert) { + var Status = makeEnum(function () { + }, [ + 'assigned', + 'complete' + ]); + var status = new Status(['assigned']); + assert.ok(status[canSymbol.for('can.isMember')]('assigned'), 'assigned is member'); + }); +}); +/*can-query-logic@1.2.2#src/types/values-and-test*/ +define('can-query-logic@1.2.2#src/types/values-and-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './keys-and', + './values-and', + './values-not', + './comparisons' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var KeysAnd = require('./keys-and'); + var ValuesAnd = require('./values-and'); + var ValuesNot = require('./values-not'); + var is = require('./comparisons'); + QUnit.module('can-query-logic/types/values-and'); + QUnit.test('works', function (assert) { + var allAndNot = new ValuesAnd([ + new KeysAnd({ tags: new is.All(['sbux']) }), + new KeysAnd({ tags: new ValuesNot(new is.All(['dfw'])) }) + ]); + assert.equal(allAndNot.isMember({ tags: ['sbux'] }), true); + assert.equal(allAndNot.isMember({ + tags: [ + 'sbux', + 'dfw' + ] + }), false); + }); +}); +/*can-query-logic@1.2.2#can-query-logic*/ +define('can-query-logic@1.2.2#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.2.2#compat/compat*/ +define('can-query-logic@1.2.2#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.2.2#compat/prop_tests/boolean_test*/ +define('can-query-logic@1.2.2#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'); + QUnit.test('boolean set.difference', function (assert) { + var prop = props.boolean('completed'); + var res = set.difference({}, { completed: true }, prop); + assert.deepEqual(res, { completed: false }, 'inverse of true'); + res = set.difference({}, { completed: false }, prop); + assert.deepEqual(res, { completed: true }, 'inverse of false'); + }); + QUnit.test('boolean set.union', function (assert) { + var prop = props.boolean('completed'); + var res = set.union({ completed: false }, { completed: true }, prop); + assert.deepEqual(res, {}, 'union of true and false is entire boolean set'); + }); + QUnit.test('boolean set.intersection', function (assert) { + var prop = props.boolean('completed'); + var res = set.intersection({ foo: 'bar' }, { completed: true }, prop); + assert.deepEqual(res, { + foo: 'bar', + completed: true + }, 'intersection is false (#4)'); + }); + QUnit.test('strings false and true are treated as booleans', function (assert) { + var prop = props.boolean('completed'); + var res; + res = set.isSubset({}, { completed: 'true' }, prop); + assert.ok(!res, '{} and \'true\' not a subset'); + res = set.isSubset({}, { completed: 'false' }, prop); + assert.ok(!res, '{} and \'false\' not a subset'); + res = set.isSubset({ completed: 'true' }, {}, prop); + assert.ok(res, 'subset'); + res = set.isSubset({ completed: 'false' }, {}, prop); + assert.ok(res, 'subset'); + res = set.union({ completed: 'false' }, { completed: 'true' }, prop); + assert.deepEqual(res, {}, 'union of true and false is entire boolean set'); + res = set.isEqual({ completed: false }, { completed: 'false' }, prop); + assert.ok(res, 'false and \'false\''); + }); +}); +/*can-query-logic@1.2.2#compat/prop_tests/enum_test*/ +define('can-query-logic@1.2.2#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'); + QUnit.test('enum set.intersection', function (assert) { + var prop = props['enum']('type', [ + 'new', + 'prep', + 'deliver', + 'delivered' + ]); + var res = set.intersection({}, { type: 'new' }, prop); + assert.deepEqual(res, { type: 'new' }, 'single enum intersected with universal set is idempotent'); + res = set.intersection({}, { + type: [ + 'new', + 'prep' + ] + }, prop); + assert.deepEqual(res, { + type: [ + 'new', + 'prep' + ] + }, 'array enum intersected with unversal set is idempotent'); + res = set.intersection({ type: ['prep'] }, { + type: [ + 'new', + 'prep' + ] + }, prop); + assert.deepEqual(res, { type: 'prep' }, 'items v items intersection'); + res = set.intersection({ type: [] }, { + type: [ + 'new', + 'prep' + ] + }, prop); + assert.deepEqual(res, set.EMPTY, 'empty v array intersection'); + res = set.intersection({ type: 'new' }, {}, prop); + assert.deepEqual(res, { type: 'new' }, 'single v all'); + }); + QUnit.test('enum set.difference', function (assert) { + var prop = props['enum']('type', [ + 'new', + 'prep', + 'deliver', + 'delivered' + ]), res; + res = set.difference({}, { type: 'new' }, prop); + assert.deepEqual(res, { + type: [ + 'prep', + 'deliver', + 'delivered' + ] + }, 'difference from universal set'); + res = set.difference({}, { + type: [ + 'new', + 'prep' + ] + }, prop); + assert.deepEqual(res, { + type: [ + 'deliver', + 'delivered' + ] + }, 'difference from universal set'); + res = set.difference({ type: ['prep'] }, { + type: [ + 'new', + 'prep' + ] + }, prop); + assert.deepEqual(res, set.EMPTY, 'difference from a superset'); + res = set.difference({}, { + type: [ + 'new', + 'prep' + ] + }, prop); + assert.deepEqual(res, { + type: [ + 'deliver', + 'delivered' + ] + }, 'empty enum definition is same as universal set'); + res = set.difference({ type: 'new' }, {}, prop); + assert.deepEqual(res, set.EMPTY, 'all'); + }); + QUnit.test('enum set.union', function (assert) { + var prop = props['enum']('type', [ + 'new', + 'prep', + 'deliver', + 'delivered' + ]); + var res = set.union({}, { type: 'new' }, prop); + assert.deepEqual(res, {}, 'all'); + res = set.union({}, { + type: [ + 'new', + 'prep' + ] + }, prop); + assert.deepEqual(res, {}, 'intersection'); + res = set.union({ type: ['prep'] }, { + type: [ + 'new', + 'prep' + ] + }, prop); + assert.deepEqual(res, { + type: [ + 'prep', + 'new' + ] + }, 'union of a superset is superset'); + res = set.union({}, { + type: [ + 'new', + 'prep' + ] + }, prop); + assert.deepEqual(res, {}, 'intersection'); + res = set.union({ type: 'new' }, {}, prop); + assert.deepEqual(res, {}, 'all'); + res = set.union({ + type: [ + 'deliver', + 'delivered' + ] + }, { + type: [ + 'new', + 'prep' + ] + }, prop); + assert.deepEqual(res, {}, 'intersection'); + }); + QUnit.test('enum set.equal', function (assert) { + var prop = props['enum']('type', [ + 'new', + 'prep', + 'deliver', + 'delivered' + ]), res; + res = set.isEqual({}, { + type: [ + 'new', + 'prep', + 'deliver', + 'delivered' + ] + }, prop); + assert.deepEqual(res, true, 'subset of all possible enums is the same as universal set'); + res = set.isEqual({ type: ['prep'] }, { type: ['prep'] }, prop); + assert.deepEqual(res, true, 'identical sets with single array enum are equal'); + res = set.isEqual({ type: 'prep' }, { type: 'prep' }, prop); + assert.deepEqual(res, true, 'identical sets with single property enum are equal'); + res = set.isEqual({ type: 'new' }, { type: 'prep' }, prop); + assert.deepEqual(res, false, 'two sets with different enum properties are not equal'); + }); + QUnit.test('enum set.isSubset', function (assert) { + var prop = props['enum']('type', [ + 'new', + 'prep', + 'deliver', + 'delivered' + ]); + var res = set.isSubset({}, { type: 'new' }, prop); + assert.deepEqual(res, false, 'universal set is not a subset'); + res = set.isSubset({ type: 'new' }, {}, prop); + assert.deepEqual(res, true, 'any single enum is a subset of universal set'); + res = set.isSubset({}, { + type: [ + 'new', + 'prep', + 'deliver', + 'delivered' + ] + }, prop); + assert.deepEqual(res, true, 'enum set matching definition of universal set is a subset of universal set'); + res = set.isSubset({ type: ['prep'] }, { type: ['prep'] }, prop); + assert.deepEqual(res, true, 'any list of possible enums are subset of universal set'); + res = set.isSubset({ type: 'prep' }, { type: 'prep' }, prop); + assert.deepEqual(res, true, 'intersection'); + res = set.isSubset({ type: 'new' }, { type: 'prep' }, prop); + assert.deepEqual(res, false, 'all'); + res = set.isSubset({ type: 'prep' }, { + type: [ + 'new', + 'prep', + 'deliver', + 'delivered' + ] + }, prop); + assert.deepEqual(res, true, 'intersection'); + }); +}); +/*can-query-logic@1.2.2#compat/prop_tests/id_test*/ +define('can-query-logic@1.2.2#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'); + QUnit.test('id set.difference', function (assert) { + var idProps = props.id('color'); + var res; + res = set.difference({ color: 'red' }, { color: 'blue' }, idProps); + assert.deepEqual(res, { color: 'red' }, 'id changes always false'); + res = set.difference({ color: 'red' }, {}, idProps); + assert.deepEqual(res, set.EMPTY, 'id removal always false'); + res = set.difference({}, { color: 'blue' }, idProps); + assert.deepEqual(res, set.UNDEFINABLE, 'id addition always true'); + }); + QUnit.test('id set.difference with where', function (assert) { + 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); + assert.deepEqual(res, { + color: 'red', + type: [ + 'light', + 'dark' + ] + }, 'id changes always false'); + res = set.difference({ + color: 'red', + type: [ + 'light', + 'dark' + ] + }, { type: 'light' }, algebra); + assert.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); + assert.deepEqual(res, set.UNDEFINABLE, 'id addition always true'); + res = set.difference({ + type: [ + 'light', + 'dark' + ] + }, { type: 'light' }, algebra); + assert.deepEqual(res, { type: 'dark' }, 'no id clause, fall back to where'); + res = set.difference({ + color: 'red', + type: [ + 'light', + 'dark' + ] + }, { + color: 'red', + type: 'light' + }, algebra); + assert.deepEqual(res, { + color: 'red', + type: 'dark' + }, 'no id change, fall back to where'); + }); +}); +/*can-query-logic@1.2.2#compat/prop_tests/rangeInclusive_test*/ +define('can-query-logic@1.2.2#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'); + QUnit.test('rangeInclusive set.equal', function (assert) { + assert.ok(set.isEqual({ + start: 0, + end: 100 + }, { + start: 0, + end: 100 + }, props.rangeInclusive('start', 'end')), 'they are equal'); + assert.ok(!set.isEqual({ + start: 0, + end: 100 + }, { + start: 0, + end: 101 + }, props.rangeInclusive('start', 'end')), 'they are not equal'); + assert.ok(!set.isEqual({ + start: 0, + end: 100 + }, { + start: 1, + end: 100 + }, props.rangeInclusive('start', 'end')), 'they are not equal'); + }); + QUnit.test('rangeInclusive set.isSubset', function (assert) { + assert.ok(set.isSubset({ + start: 0, + end: 100 + }, { + start: 0, + end: 100 + }, props.rangeInclusive('start', 'end')), 'self is a subset'); + assert.ok(set.isSubset({ + start: 0, + end: 100 + }, { + start: 0, + end: 101 + }, props.rangeInclusive('start', 'end')), 'end extends past subset'); + assert.ok(!set.isSubset({ + start: 0, + end: 101 + }, { + start: 0, + end: 100 + }, props.rangeInclusive('start', 'end')), 'non-subset extends past end'); + assert.ok(set.isSubset({ + start: 1, + end: 100 + }, { + start: 0, + end: 100 + }, props.rangeInclusive('start', 'end')), 'start extends before subset'); + assert.ok(!set.isSubset({ + start: 0, + end: 100 + }, { + start: 1, + end: 100 + }, props.rangeInclusive('start', 'end')), 'non-subset extends before start'); + }); + QUnit.test('rangeInclusive set.difference', function (assert) { + var prop = props.rangeInclusive('start', 'end'); + var res = set.difference({ + start: 0, + end: 99 + }, { + start: 50, + end: 101 + }, prop); + assert.deepEqual(res, { + start: 0, + end: 49 + }, 'got a diff'); + res = set.difference({}, { + start: 0, + end: 10 + }, prop); + assert.deepEqual(res, { start: 11 }, 'universal set'); + res = set.difference({ + start: 0, + end: 49 + }, { + start: 50, + end: 101 + }, prop); + assert.deepEqual(res, { + start: 0, + end: 49 + }, 'side by side'); + res = set.difference({ + start: 0, + end: 49 + }, { + start: 0, + end: 20 + }, prop); + assert.deepEqual(res, { + start: 21, + end: 49 + }, 'first set extends past second'); + res = set.difference({ + start: 0, + end: 49 + }, { + start: 20, + end: 49 + }, prop); + assert.deepEqual(res, { + start: 0, + end: 19 + }, 'first set starts before second'); + }); + QUnit.test('rangeInclusive set.union', function (assert) { + var prop = props.rangeInclusive('start', 'end'); + var res = set.union({ + start: 0, + end: 99 + }, { + start: 50, + end: 101 + }, prop); + assert.deepEqual(res, { + start: 0, + end: 101 + }, 'got a union'); + res = set.union({}, { + start: 0, + end: 10 + }, prop); + assert.deepEqual(res, {}, 'universal set'); + res = set.union({ + start: 100, + end: 199 + }, { + start: 200, + end: 299 + }, prop); + assert.deepEqual(res, { + start: 100, + end: 299 + }, 'no intersection'); + res = set.union({ + start: 200, + end: 299 + }, { + start: 100, + end: 199 + }, prop); + assert.deepEqual(res, { + start: 100, + end: 299 + }, 'no intersection with either argument order'); + res = set.union({ + start: 200, + end: 299 + }, { + start: 100, + end: 209 + }, prop); + assert.deepEqual(res, { + start: 100, + end: 299 + }, 'sets can intersect'); + res = set.union({ + start: 100, + end: 209 + }, { + start: 200, + end: 299 + }, prop); + assert.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); + assert.deepEqual(res, { + start: 100, + end: 299 + }, 'first set contains second'); + res = set.union({ + start: 100, + end: 299 + }, { + start: 103, + end: 209 + }, prop); + assert.deepEqual(res, { + start: 100, + end: 299 + }, 'second set contains first'); + res = set.union({ + start: 100, + end: 299 + }, { + start: 100, + end: 299 + }, prop); + assert.deepEqual(res, { + start: 100, + end: 299 + }, 'union of identical sets is the same as those sets'); + }); + QUnit.test('rangeInclusive set.count', function (assert) { + var prop = props.rangeInclusive('start', 'end'); + var res = set.count({ + start: 0, + end: 99 + }, prop); + assert.equal(res, 100, 'count is right'); + }); + QUnit.test('rangeInclusive set.intersection', function (assert) { + var prop = props.rangeInclusive('start', 'end'); + var res = set.intersection({ + start: 0, + end: 99 + }, { + start: 50, + end: 101 + }, prop); + assert.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); + assert.deepEqual(res, set.UNDEFINABLE, 'got a intersection'); + }); + QUnit.test('rangeInclusive with string numbers (#17)', function (assert) { + var algebra = new set.Algebra(props.rangeInclusive('start', 'end')); + assert.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 } + ]); + assert.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 } + ]); + assert.deepEqual(res, [ + { id: 1 }, + { id: 2 }, + { id: 3 }, + { id: 4 } + ], '.unionMembers'); + }); +}); +/*can-query-logic@1.2.2#compat/prop_tests/offsetLimit_test*/ +define('can-query-logic@1.2.2#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'); + QUnit.test('offsetLimit set.equal', function (assert) { + assert.ok(set.isEqual({ + offset: 0, + limit: 99 + }, { + offset: 0, + limit: 99 + }, props.offsetLimit('offset', 'limit')), 'they are equal'); + assert.ok(!set.isEqual({ + offset: 0, + limit: 100 + }, { + offset: 0, + limit: 101 + }, props.offsetLimit('offset', 'limit')), 'they are not equal'); + assert.ok(!set.isEqual({ + offset: 0, + limit: 100 + }, { + offset: 1, + limit: 100 + }, props.offsetLimit('offset', 'limit')), 'they are not equal'); + }); + QUnit.test('offsetLimit set.union', function (assert) { + var prop = props.offsetLimit('offset', 'limit'), res; + res = set.union({ + offset: 0, + limit: 100 + }, { + offset: 50, + limit: 52 + }, prop); + assert.deepEqual(res, { + offset: 0, + limit: 102 + }, 'got a union'); + res = set.union({}, { + offset: 0, + limit: 10 + }, prop); + assert.deepEqual(res, {}, 'universal set'); + res = set.union({ + offset: 100, + limit: 100 + }, { + offset: 200, + limit: 100 + }, prop); + assert.deepEqual(res, { + offset: 100, + limit: 200 + }, 'no intersection'); + res = set.union({ + offset: 200, + limit: 100 + }, { + offset: 100, + limit: 100 + }, prop); + assert.deepEqual(res, { + offset: 100, + limit: 200 + }, 'no intersection with either argument order'); + res = set.union({ + offset: 100, + limit: 110 + }, { + offset: 200, + limit: 100 + }, prop); + assert.deepEqual(res, { + offset: 100, + limit: 200 + }, 'sets can intersect with either argument order'); + }); + QUnit.test('rangeInclusive set.count', function (assert) { + var prop = props.offsetLimit('offset', 'limit'); + var res = set.count({ + offset: 0, + limit: 100 + }, prop); + assert.equal(res, 100, 'count is right'); + }); + QUnit.test('rangeInclusive set.intersection', function (assert) { + var prop = props.offsetLimit('offset', 'limit'); + var res = set.intersection({ + offset: 0, + limit: 100 + }, { + offset: 50, + limit: 52 + }, prop); + assert.deepEqual(res, { + offset: 50, + limit: 50 + }, 'got a intersection'); + }); +}); +/*can-query-logic@1.2.2#compat/prop_tests/sort_test*/ +define('can-query-logic@1.2.2#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'); + QUnit.test('set.difference', function (assert) { + var prop = props.sort('sort'), res; + res = set.difference({ sort: 'foo' }, { completed: true }, prop); + assert.deepEqual(res, set.UNDEFINABLE, 'diff should be true'); + res = set.difference({ completed: true }, { + completed: true, + sort: 'foo' + }, prop); + assert.equal(res, set.EMPTY, 'the same except for sort'); + res = set.difference({ completed: true }, { sort: 'foo' }, prop); + assert.equal(res, set.EMPTY, 'nothing in completed:true that isn\'t in everything'); + res = set.difference({ completed: true }, { + foo: 'bar', + sort: 'foo' + }, prop); + assert.equal(res, set.UNDEFINABLE, 'we can diff, it exists, we don\'t know what it is though'); + }); + QUnit.test('set.union', function (assert) { + var prop = props.sort('sort'), res; + res = set.union({ sort: 'name' }, { completed: true }, prop); + assert.deepEqual(res, {}, 'set / subset sort left'); + res = set.union({}, { + completed: true, + sort: 'name' + }, prop); + assert.deepEqual(res, {}, 'set / subset sort right'); + res = set.union({ sort: 'name' }, { + completed: true, + sort: 'namer' + }, prop); + assert.deepEqual(res, {}, 'set / subset both sorts'); + res = set.union({ completed: true }, { sort: 'foo' }, prop); + assert.deepEqual(res, {}, 'subset / set'); + res = set.union({ + foo: 'bar', + sort: 'foo' + }, { foo: 'bar' }, prop); + assert.deepEqual(res, { foo: 'bar' }, 'equal'); + res = set.union({ foo: 'bar' }, { + foo: 'zed', + sort: 'foo' + }, prop); + assert.deepEqual(res, { + foo: [ + 'bar', + 'zed' + ] + }, 'values not equal'); + res = set.union({ + foo: 'bar', + sort: 'foo' + }, { name: 'A' }, prop); + assert.deepEqual(res, set.UNDEFINABLE, 'values not equal'); + }); + QUnit.test('set.union Array', function (assert) { + var prop = props.sort('sort'); + var res = set.union({ + foo: [ + 'a', + 'b' + ], + sort: 'foo' + }, { + foo: [ + 'a', + 'c' + ] + }, prop); + assert.deepEqual(res, { + foo: [ + 'a', + 'b', + 'c' + ] + }, 'set / subset'); + }); + QUnit.test('set.count', function (assert) { + assert.ok(set.count({ sort: 'name' }) === Infinity, 'defaults to infinity'); + assert.ok(set.count({ + foo: 'bar', + sort: 'foo' + }, {}) === Infinity, 'defaults to infinity'); + }); + QUnit.test('set.intersection', function (assert) { + var prop = props.sort('sort'), res; + res = set.intersection({}, { sort: 'name' }, prop); + assert.deepEqual(res, {}, 'no sort if only one is sorted'); + res = set.intersection({ sort: 'name' }, { sort: 'name' }, prop); + assert.deepEqual(res, { sort: 'name' }, 'equal'); + res = set.intersection({ type: 'new' }, { + sort: 'name', + userId: 5 + }, prop); + assert.deepEqual(res, { + type: 'new', + userId: 5 + }, ''); + res = set.intersection({ + type: 'new', + sort: 'age' + }, { + sort: 'name', + userId: 5 + }, prop); + assert.deepEqual(res, { + type: 'new', + userId: 5 + }, ''); + }); + QUnit.test('set.intersection Array', function (assert) { + var prop = props.sort('sort'); + var res = set.intersection({ + foo: [ + 'a', + 'b' + ], + sort: 'foo' + }, { + foo: [ + 'a', + 'c' + ] + }, prop); + assert.deepEqual(res, { foo: 'a' }, 'intersection'); + }); + QUnit.test('set.isSubset', function (assert) { + var algebra = new set.Algebra(props.sort('sort'), set.props.ignore('foo'), set.props.ignore('bar'), set.props.ignore('kind'), set.props.ignore('count')); + assert.ok(algebra.isSubset({ + type: 'FOLDER', + sort: 'thing' + }, { type: 'FOLDER' }), 'equal sets with sort on the left'); + assert.ok(algebra.isSubset({ type: 'FOLDER' }, { + type: 'FOLDER', + sort: 'thing' + }), 'equal sets with sort on the right'); + assert.ok(algebra.isSubset({ + type: 'FOLDER', + parentId: 5, + sort: 'thing' + }, { type: 'FOLDER' }), 'sub set with sort on the left'); + assert.ok(algebra.isSubset({ + type: 'FOLDER', + parentId: 5 + }, { + type: 'FOLDER', + sort: 'thing' + }), 'sub set with sort on the right'); + assert.ok(!algebra.isSubset({ + type: 'FOLDER', + sort: 'thing' + }, { + type: 'FOLDER', + parentId: 5 + }), 'wrong way with sort on the left'); + assert.ok(!algebra.isSubset({ type: 'FOLDER' }, { + type: 'FOLDER', + parentId: 5, + sort: 'thing' + }), 'wrong way with sort on the right'); + assert.ok(!algebra.isSubset({ + type: 'FOLDER', + parentId: 7, + sort: 'thing' + }, { + type: 'FOLDER', + parentId: 5 + }), 'different values with sort on the left'); + assert.ok(!algebra.isSubset({ + type: 'FOLDER', + parentId: 7 + }, { + type: 'FOLDER', + parentId: 5, + sort: 'thing' + }), 'different values with sort on the right'); + }); + QUnit.test('set.isSubset with range', function (assert) { + 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) { + 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) { + 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 () { + }, + superLeft: function (setA, setB) { + setB.type = 'apples'; + }, + superRight: function (setA) { + 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); + assert.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); + }); + QUnit.test('set.index', function (assert) { + 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' }); + assert.equal(index, 2); + }); + QUnit.test('set.filterMembers (#14)', function (assert) { + 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' + } + ]); + assert.deepEqual(subset, [ + { + id: 4, + name: 'g' + }, + { + id: 2, + name: 'j' + }, + { + id: 3, + name: 'm' + }, + { + id: 1, + name: 's' + } + ]); + }); + QUnit.test('set.unionMembers', function (assert) { + 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 + } + ]); + assert.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 + } + ]); + }); + QUnit.test('set.union keeps sort', function (assert) { + var algebra = new set.Algebra(props.sort('sort'), props.boolean('complete')); + var union = algebra.union({ + sort: 'name', + complete: true + }, { + sort: 'name', + complete: false + }); + assert.deepEqual(union, { sort: 'name' }); + }); + QUnit.test('paginated and sorted is subset (#17)', function (assert) { + 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' + }); + assert.equal(res, undefined, 'parent:paginate+order child:paginate+order (different order)'); + res = algebra.isSubset({ + start: 0, + end: 100, + sort: 'name' + }, { sort: 'name' }); + assert.equal(res, true, 'parent:order child:paginate+order'); + res = algebra.isSubset({ sort: 'name' }, { sort: 'name' }); + assert.equal(res, true, 'parent:order child:order (same)'); + res = algebra.isSubset({ sort: 'name' }, { sort: 'age' }); + assert.equal(res, true, 'parent:order child:order (different)'); + res = algebra.isSubset({ + start: 0, + end: 100 + }, { sort: 'name' }); + assert.equal(res, true, 'parent:order child:paginate'); + res = algebra.isSubset({ + start: 0, + end: 100, + sort: 'age' + }, { sort: 'name' }); + assert.equal(res, true, 'parent:order child:paginate+order'); + res = algebra.isSubset({ + start: 0, + end: 100, + sort: 'name' + }, { + start: 0, + end: 100 + }); + assert.equal(res, undefined, 'parent:paginate child:paginate+order'); + res = algebra.isSubset({ sort: 'name' }, { + start: 0, + end: 100 + }); + assert.equal(res, false, 'parent:paginate child:order (same)'); + res = algebra.isSubset({ + start: 0, + end: 100, + sort: 'name' + }, {}); + assert.equal(res, true, 'parent:-- child:paginate+order'); + res = algebra.isSubset({ + start: 10, + end: 90, + sort: 'name' + }, { + start: 0, + end: 100, + sort: 'name' + }); + assert.equal(res, true, 'child in smaller range, same sort'); + res = algebra.isSubset({ + start: 10, + end: 90, + sort: 'name' + }, { + start: 0, + end: 100, + sort: 'age' + }); + assert.equal(res, undefined, 'child in smaller range, but different sort'); + }); +}); +/*can-query-logic@1.2.2#compat/prop_tests/translate_test*/ +define('can-query-logic@1.2.2#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 (assert) { + 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 + } + }); + assert.ok(res, 'count ignored'); + res = algebra.isEqual({ $where: { type: 'FOLDER' } }, { $where: { type: 'FOLDER' } }); + assert.ok(res, 'folder case ignored'); + }); + QUnit.test('set.isSubset', function (assert) { + 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' } }); + assert.ok(res, 'equal sets'); + res = algebra.isSubset({ + $where: { + type: 'FOLDER', + parentId: 5 + } + }, { $where: { type: 'FOLDER' } }); + assert.ok(res, 'sub set'); + res = algebra.isSubset({ $where: { type: 'FOLDER' } }, { + $where: { + type: 'FOLDER', + parentId: 5 + } + }); + assert.ok(!res, 'wrong way'); + res = algebra.isSubset({ + $where: { + type: 'FOLDER', + parentId: 7 + } + }, { + $where: { + type: 'FOLDER', + parentId: 5 + } + }); + assert.ok(!res, 'different values'); + res = algebra.isSubset({ + $where: { + type: 'FOLDER', + count: 5 + } + }, { $where: { type: 'FOLDER' } }); + assert.ok(res, 'count ignored'); + res = algebra.isSubset({ + $where: { + type: 'FOLDER', + category: 'tree' + } + }, { + $where: { + type: 'FOLDER', + foo: true, + bar: true + } + }); + assert.ok(res, 'understands a subset'); + res = algebra.isSubset({ + $where: { + type: 'FOLDER', + foo: true, + bar: true + } + }, { + $where: { + type: 'FOLDER', + kind: 'tree' + } + }); + assert.ok(res, 'ignores nulls'); + }); + QUnit.test('set.isProperSubset', function (assert) { + var algebra = new set.Algebra(new set.Translate('where', '$where')); + assert.equal(algebra.isProperSubset({ $where: { foo: 'bar' } }, { $where: {} }), true); + assert.equal(algebra.isProperSubset({ $where: {} }, { $where: {} }), false); + assert.equal(algebra.isProperSubset({ $where: {} }, { $where: { foo: 'bar' } }), false); + }); + QUnit.test('set.difference', function (assert) { + var algebra = new set.Algebra(new set.Translate('where', '$where')); + var res = algebra.difference({ $where: {} }, { $where: { completed: true } }); + assert.equal(res, querySet.UNDEFINABLE, 'diff should be true'); + res = algebra.difference({ $where: { completed: true } }, { $where: { completed: true } }); + assert.equal(res, querySet.EMPTY); + res = algebra.difference({ $where: { completed: true } }, { $where: {} }); + assert.equal(res, querySet.EMPTY); + res = algebra.difference({ $where: { completed: true } }, { $where: { userId: 5 } }); + assert.equal(res, querySet.UNDEFINABLE); + }); + QUnit.test('set.union', function (assert) { + var algebra = new set.Algebra(new set.Translate('where', '$where')); + var res = algebra.union({ $where: {} }, { $where: { completed: true } }); + assert.deepEqual(res, {}, 'set / subset'); + res = algebra.union({ $where: { completed: true } }, { $where: {} }); + assert.deepEqual(res, {}, 'subset / set'); + res = algebra.union({ $where: { foo: 'bar' } }, { $where: { foo: 'bar' } }); + assert.deepEqual(res, { $where: { foo: 'bar' } }, 'equal'); + res = algebra.union({ $where: { foo: 'bar' } }, { $where: { foo: 'zed' } }); + assert.deepEqual(res, { + $where: { + foo: [ + 'bar', + 'zed' + ] + } + }, 'values not equal'); + res = algebra.union({ $where: { foo: 'bar' } }, { $where: { name: 'A' } }); + assert.deepEqual(res, querySet.UNDEFINABLE, 'values not equal'); + }); + QUnit.test('set.union Array', function (assert) { + var algebra = new set.Algebra(new set.Translate('where', '$where')); + var res = algebra.union({ + $where: { + foo: [ + 'a', + 'b' + ] + } + }, { + $where: { + foo: [ + 'a', + 'c' + ] + } + }); + assert.deepEqual(res, { + $where: { + foo: [ + 'a', + 'b', + 'c' + ] + } + }, 'set / subset'); + }); + QUnit.test('set.intersection', function (assert) { + var algebra = new set.Algebra(new set.Translate('where', '$where')), res; + res = algebra.intersection({ $where: {} }, { $where: { completed: true } }); + assert.deepEqual(res, { $where: { completed: true } }, 'set / subset'); + res = algebra.intersection({ $where: { completed: true } }, { $where: {} }); + assert.deepEqual(res, { $where: { completed: true } }, 'subset / set'); + res = algebra.intersection({ $where: { foo: 'bar' } }, { $where: { foo: 'bar' } }); + assert.deepEqual(res, { $where: { foo: 'bar' } }, 'equal'); + res = algebra.intersection({ $where: { foo: 'bar' } }, { $where: { foo: 'zed' } }); + assert.deepEqual(res, querySet.EMPTY, 'values not equal'); + res = algebra.intersection({ $where: { foo: 'bar' } }, { $where: { completed: true } }); + assert.deepEqual(res, { + $where: { + foo: 'bar', + completed: true + } + }, 'intersection should combine definitions'); + }); + QUnit.test('set.intersection Array', function (assert) { + var algebra = new set.Algebra(new set.Translate('where', '$where')); + var res = algebra.intersection({ + $where: { + foo: [ + 'a', + 'b' + ] + } + }, { + $where: { + foo: [ + 'a', + 'c' + ] + } + }); + assert.deepEqual(res, { $where: { foo: 'a' } }, 'intersection'); + }); + QUnit.test('set.has', function (assert) { + 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')); + assert.ok(algebra.isMember({ $where: { someId: 5 } }, { + someId: 5, + name: 'foo' + }), 'contains'); + var res; + res = algebra.isMember({ $where: { type: 'FOLDER' } }, { type: 'FOLDER' }); + assert.ok(res, 'equal sets'); + res = algebra.isMember({ + $where: { + type: 'FOLDER', + parentId: 5 + } + }, { type: 'FOLDER' }); + assert.equal(res, false, 'doesnt match'); + res = algebra.isMember({ $where: { type: 'FOLDER' } }, { + type: 'FOLDER', + parentId: 5 + }); + assert.ok(true, 'is a subset'); + res = algebra.isMember({ + $where: { + type: 'FOLDER', + parentId: 7 + } + }, { + type: 'FOLDER', + parentId: 5 + }); + assert.ok(!res, 'different values'); + res = algebra.isMember({ + $where: { + type: 'FOLDER', + count: 5 + } + }, { type: 'FOLDER' }, { count: ignoreProp }); + assert.ok(res, 'count ignored'); + res = algebra.isMember({ + $where: { + type: 'FOLDER', + kind: 'tree' + } + }, { + type: 'FOLDER', + foo: true, + bar: true + }); + assert.ok(res, 'understands a subset'); + res = algebra.isMember({ + $where: { + type: 'FOLDER', + foo: true, + bar: true + } + }, { + type: 'FOLDER', + kind: 'tree' + }); + assert.ok(res, 'ignores nulls'); + }); +}); +/*can-query-logic@1.2.2#compat/compat-test*/ +define('can-query-logic@1.2.2#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.2.2#test/special-comparison-logic-test*/ +define('can-query-logic@1.2.2#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 (assert) { + 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); + assert.deepEqual(q3, { + where: { + first: 'FIRST', + second: 'SECOND' + } + }, 'got intersection'); + }); + var stringIncludes = function (strA, strB) { + return strA.indexOf(strB) >= 0; + }; + QUnit.test('Searchable string', function (assert) { + 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' } }); + assert.equal(res, true, 'is subset'); + res = todoQueryLogic.isSubset({ filter: { name: 'eat' } }, { filter: { name: 'beat' } }); + assert.equal(res, false, 'not subset'); + var hydrated = todoQueryLogic.hydrate({ filter: { name: 'eat' } }); + assert.deepEqual(hydrated.filter, new QueryLogic.KeysAnd({ name: new SearchableStringSet('eat') }), 'hydrated right'); + res = todoQueryLogic.union({ filter: { name: 'eat' } }, { filter: { name: 'foo' } }); + assert.deepEqual(res, { + filter: { + name: [ + 'eat', + 'foo' + ] + } + }); + assert.ok(todoQueryLogic.isMember({ filter: { name: 'eat' } }, { + id: 1, + name: 'eat beans' + }), 'isMember true'); + assert.notOk(todoQueryLogic.isMember({ filter: { name: 'eat' } }, { + id: 1, + name: 'foo bar' + }), 'isMember false'); + }); + QUnit.test('value type', function (assert) { + 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() + } + ]); + assert.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()] } }); + assert.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; + }); + assert.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() + }); + assert.equal(index, 4, 'added at the end'); + }); + QUnit.test('sort a type that is similar to the member values (#31)', function (assert) { + function StringIgnoreCaseSet(value) { + this.value = value; + } + StringIgnoreCaseSet.prototype.valueOf = function () { + return this.value.toLowerCase(); + }; + canReflect.assignSymbols(StringIgnoreCaseSet.prototype, { + 'can.serialize': function () { + return this.value; + } + }); + var StringIgnoreCase = canReflect.assignSymbols({}, { + 'can.SetType': StringIgnoreCaseSet, + 'can.new': function (value) { + return value; + } + }); + var queryLogic = new QueryLogic({ + keys: { name: StringIgnoreCase }, + identity: ['id'] + }); + var filter = queryLogic.filterMembers({ sort: 'name' }, [ + { + id: 1, + name: 'grab coffee' + }, + { + id: 2, + name: 'finish these docs' + }, + { + id: 3, + name: 'Learn CanJS' + } + ]); + assert.deepEqual([ + { + id: 2, + name: 'finish these docs' + }, + { + id: 1, + name: 'grab coffee' + }, + { + id: 3, + name: 'Learn CanJS' + } + ], filter); + }); +}); +/*can-query-logic@1.2.2#test/make-enum-logic-test*/ +define('can-query-logic@1.2.2#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 (assert) { + var unionResult = algebra.union({ + filter: { + name: 'Justin', + status: 'red' + } + }, { + filter: { + name: 'Justin', + status: 'green' + } + }); + assert.deepEqual(unionResult, { + filter: { + name: 'Justin', + status: [ + 'red', + 'green' + ] + } + }); + }); + QUnit.test('automatic enum', function (assert) { + 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 } }); + assert.deepEqual(res, { + filter: { + complete: [ + false, + undefined, + null + ] + } + }, 'enum works'); + }); + QUnit.test('makeEnum from homepage with schema type', function (assert) { + 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' } }); + assert.deepEqual(unionQuery, {}); + }); + QUnit.test('makeEnum from homepage', function (assert) { + 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' } }); + assert.deepEqual(unionQuery, {}); + }); +}); +/*can-query-logic@1.2.2#test/maybe-type-test*/ +define('can-query-logic@1.2.2#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 (assert) { + 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 todoQueryLogic = new QueryLogic({ keys: { age: MaybeNumber } }); + var unionized = todoQueryLogic.union({ filter: { age: 7 } }, { filter: { age: '07' } }); + assert.deepEqual(unionized, { filter: { age: 7 } }, 'string numbers are converted to numbers'); + }); + QUnit.test('MaybeDate', function (assert) { + 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 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); + assert.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.2.2#can-query-logic-test*/ +define('can-query-logic@1.2.2#can-query-logic-test', [ + 'require', + 'exports', + 'module', + './src/set-test', + './src/helpers-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-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', + './src/types/values-and-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/helpers-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-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('./src/types/values-and-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 (assert) { + var unionResult = algebra.union({ filter: { name: 'Ramiya' } }, { filter: { name: 'Bohdi' } }); + assert.deepEqual(unionResult, { + filter: { + name: { + $in: [ + 'Ramiya', + 'Bohdi' + ] + } + } + }); + }); + QUnit.test('difference', function (assert) { + var differenceResult = algebra.difference({ + filter: { + name: { + $in: [ + 'Ramiya', + 'Bohdi' + ] + } + } + }, { filter: { name: 'Bohdi' } }); + assert.deepEqual(differenceResult, { filter: { name: 'Ramiya' } }); + }); + QUnit.test('subset', function (assert) { + var subsetResult = algebra.isSubset({ filter: { name: 'Bohdi' } }, { + filter: { + name: { + $in: [ + 'Ramiya', + 'Bohdi' + ] + } + } + }); + assert.deepEqual(subsetResult, true); + }); + QUnit.test('isMember', function (assert) { + var hasResult = algebra.isMember({ filter: { name: 'Bohdi' } }, { name: 'Bohdi' }); + assert.deepEqual(hasResult, true); + }); + QUnit.test('filterMembers basics', function (assert) { + var subset = algebra.filterMembers({ + filter: { + name: { + $in: [ + 'Bohdi', + 'Ramiya' + ] + } + } + }, {}, [ + { name: 'Bohdi' }, + { name: 'Ramiya' }, + { name: 'Payal' }, + { name: 'Justin' } + ]); + assert.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' } + ]); + assert.deepEqual(subset, [ + { name: 'Payal' }, + { name: 'Justin' } + ]); + }); + QUnit.test('unionMembers basics', function (assert) { + var union = algebra.unionMembers({ filter: { name: 'Bohdi' } }, { filter: { name: 'Ramiya' } }, [{ + name: 'Bohdi', + id: 1 + }], [{ + name: 'Ramiya', + id: 2 + }]); + assert.deepEqual(union, [ + { + name: 'Bohdi', + id: 1 + }, + { + name: 'Ramiya', + id: 2 + } + ]); + }); + QUnit.test('count basics', function (assert) { + assert.equal(algebra.count({}), Infinity); + assert.equal(algebra.count({ + page: { + start: 1, + end: 2 + } + }), 2); + }); + QUnit.test('index basics', function (assert) { + var index = algebra.index({ sort: 'name' }, [ + { + id: 1, + name: 'g' + }, + { + id: 2, + name: 'j' + }, + { + id: 3, + name: 'm' + }, + { + id: 4, + name: 's' + } + ], { name: 'k' }); + assert.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' }); + assert.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' + }); + assert.equal(index, 0); + index = algebra.index({}, [ + { + id: 1, + name: 'g' + }, + { + id: 2, + name: 'j' + }, + { + id: 3, + name: 'm' + }, + { + id: 4, + name: 's' + } + ], { name: 'k' }); + assert.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 + }); + assert.equal(index, 2); + }); + QUnit.test('filterMembers with reverse sort', function (assert) { + var sortedMembers = algebra.filterMembers({ sort: '-name' }, [ + { + id: 1, + name: 'a' + }, + { + id: 2, + name: 'z' + }, + { + id: 3, + name: 'f' + }, + { + id: 4, + name: 's' + } + ]); + assert.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 (assert) { + var gt1 = new QueryLogic.GreaterThan(1); + var lte1 = new QueryLogic.LessThanEqual(1); + assert.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) }); + assert.deepEqual(QueryLogic.union(isGtJustinAndGt35, isGt25), isGt25, 'fewer clauses'); + }); +}); +/*can-value@1.1.1#test/test*/ +define('can-value@1.1.1#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 (assert) { + var outer = new SimpleMap({ inner: new SimpleMap({ key: 'hello' }) }); + var observable = canValue.bind(outer, 'inner.key'); + assert.equal(canReflect.getValue(observable), 'hello', 'getting works'); + canReflect.setValue(observable, 'aloha'); + assert.equal(outer.get('inner').get('key'), 'aloha', 'setting works'); + }); + QUnit.test('from method works', function (assert) { + var outer = { inner: { key: 'hello' } }; + var observation = canValue.from(outer, 'inner.key'); + assert.equal(canReflect.getValue(observation), 'hello', 'getting works'); + var errorThrown; + try { + canReflect.setValue(observation, 'aloha'); + } catch (error) { + errorThrown = error; + } + assert.ok(errorThrown instanceof Error, 'setting doesn\u2019t work'); + }); + if (supportsFunctionNames) { + onlyDevTest('from method returns an observation with a helpful name', function (assert) { + var outer = { inner: { key: 'hello' } }; + var observation = canValue.from(outer, 'inner.key'); + assert.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 (assert) { + var observable = canValue.with(15); + assert.equal(canReflect.getValue(observable), 15, 'getting works'); + canReflect.setValue(observable, 22); + assert.equal(canReflect.getValue(observable), 22, 'setting works'); + }); + QUnit.test('returnedBy method works', function (assert) { + var person = new SimpleMap({ + first: 'Grace', + last: 'Murray' + }); + var observable = canValue.returnedBy(function () { + return person.get('first') + ' ' + person.get('last'); + }); + assert.equal(canReflect.getValue(observable), 'Grace Murray', 'getting works'); + person.set('last', 'Hopper'); + assert.equal(canReflect.getValue(observable), 'Grace Hopper', 'setting works'); + }); + QUnit.test('returnedBy(getter(lastSet)) method works', function (assert) { + var person = new SimpleMap({ + first: 'Grace', + last: 'Murray' + }); + var observable = canValue.returnedBy(function (lastSet) { + return person.get('first') + lastSet + person.get('last'); + }, null, ' '); + assert.equal(canReflect.getValue(observable), 'Grace Murray', 'getting works'); + person.set('last', 'Hopper'); + assert.equal(canReflect.getValue(observable), 'Grace Hopper', 'setting dep works'); + observable.value = ' J '; + assert.equal(observable.value, 'Grace J Hopper', 'setting works'); + }); + QUnit.test('to method works', function (assert) { + var outer = { inner: { key: 'hello' } }; + var setProp = canValue.to(outer, 'inner.key'); + assert.equal(canReflect.getValue(setProp), setProp, 'getting the value doesn\u2019t work'); + canReflect.setValue(setProp, 'aloha'); + assert.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'); + assert.equal(newInner.get('key'), 'ciao', 'setting works after changing the inner object'); + assert.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.2#can-param*/ +define('can-param@1.1.2#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) { + var inner = obj[i]; + var shouldIncludeIndex = typeof inner === 'object'; + var arrayIndex = shouldIncludeIndex ? '[' + i + ']' : '[]'; + buildParam(prefix + arrayIndex, inner, 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.4.6#can-ajax*/ +define('can-ajax@2.4.6#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; + var isAborted = false; + promise.abort = function () { + isAborted = true; + 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); + }); + var async = o.async !== false; + 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, async); + 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 { + if (isJsonContentType && !isSimpleCors) { + data = typeof o.data === 'object' ? JSON.stringify(o.data) : o.data; + xhr.setRequestHeader('Content-Type', 'application/json'); + } else { + data = param(o.data); + xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); + } + } + } else { + xhr.setRequestHeader('Content-Type', o.contentType); + } + if (!isSimpleCors) { + xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); + } + if (o.xhrFields) { + for (var f in o.xhrFields) { + xhr[f] = o.xhrFields[f]; + } + } + function send() { + if (!isAborted) { + xhr.send(data); + } + } + if (o.beforeSend) { + var result = o.beforeSend.call(o, xhr, o); + if (canReflect.isPromise(result)) { + result.then(send).catch(deferred.reject); + return promise; + } + } + send(); + 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.2#can-make-map*/ +define('can-make-map@1.2.2#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; +}); +/*can-ajax@2.4.6#test/qunit*/ +define('can-ajax@2.4.6#test/qunit', [ + 'require', + 'exports', + 'module', + 'qunit', + '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('qunit'); + } else { + module.exports = require('steal-qunit'); + } +}); +/*can-ajax@2.4.6#test/helpers*/ +define('can-ajax@2.4.6#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.4.6#can-ajax-test*/ +define('can-ajax@2.4.6#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) { + 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('synchronous get request', function (assert) { + var done = assert.async(); + var ok = true; + ajax({ + type: 'get', + url: __dirname + '/can-ajax-test-result.json', + async: false, + success: function () { + assert.ok(ok, 'Callback happens before returning.'); + } + }).then(function () { + assert.ok(!ok, 'Promise resolves after returning'); + done(); + }); + ok = false; + }); + } + 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) { + assert.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 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.url, url); + assert.equal(typeof value['Content-Type'], 'undefined', 'Content-Type should not be set'); + }, function (reason) { + assert.notOk(reason, 'request failed with reason = ', reason); + }).then(function () { + restore(); + done(); + }); + }); + QUnit.test('abort', function (assert) { + var done = assert.async(); + var restore = makeFixture(function () { + var aborted = false; + this.open = function (type, url) { + }; + this.setRequestHeader = function (header, value) { + }; + this.send = function () { + }; + this.abort = function () { + assert.ok(true, 'called the underlying XHR.abort'); + restore(); + done(); + }; + }); + var request = ajax({ url: '/foo' }); + request.abort(); + }); + QUnit.test('abort prevents sending if beforeSend is not finished', function (assert) { + var done = assert.async(); + var restore = makeFixture(function () { + var aborted = false; + this.open = function (type, url) { + }; + this.setRequestHeader = function (header, value) { + }; + this.abort = function () { + assert.ok(true, 'XHR abort was called'); + }; + this.send = function () { + assert.notOk(true, 'should not have been called'); + }; + }); + var request = ajax({ + url: '/foo', + beforeSend: function (xhr) { + return new Promise(function (resolve) { + setTimeout(resolve, 1); + }); + } + }); + request.abort(); + setTimeout(function () { + restore(); + done(); + }, 10); + }); + QUnit.test('beforeSend', 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', + xhrFields: { 'CustomHeader': 'CustomValue' }, + beforeSend: function (xhr) { + assert.ok(xhr.hasOwnProperty('CustomHeader'), 'xhrField header set'); + xhr.setRequestHeader('Authorization', 'Bearer 123'); + } + }).then(function (value) { + assert.ok(headers.hasOwnProperty('Authorization'), 'authorization header set'); + }, function (reason) { + assert.notOk(reason, 'request failed with reason = ', reason); + }).then(function () { + restore(); + done(); + }); + }); + QUnit.test('beforeSend async', function (assert) { + var done = assert.async(); + var headers = {}; + var 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({ + url: '/foo', + beforeSend: function (xhr) { + return new Promise(function (resolve) { + setTimeout(function () { + xhr.setRequestHeader('Authorization', 'Bearer 123'); + resolve(); + }, 1); + }); + } + }).then(function (value) { + assert.ok(headers.hasOwnProperty('Authorization'), 'authorization header set'); + }, function (reason) { + assert.notOk(reason, 'request failed with reason = ', reason); + }).then(function () { + restore(); + done(); + }); + }); + QUnit.test('beforeSend rejects the ajax promise on failure', function (assert) { + var done = assert.async(); + var error = new Error(); + var restore = makeFixture(function () { + this.open = function (type, url) { + }; + this.send = function () { + assert.notOk(true, 'Should not be called'); + }; + this.setRequestHeader = function (header, value) { + }; + }); + ajax({ + url: '/foo', + beforeSend: function (xhr) { + return new Promise(function (resolve, reject) { + setTimeout(function () { + reject(error); + }, 1); + }); + } + }).then(function (value) { + assert.notOk(true, 'request should have rejected'); + }, function (reason) { + assert.ok(true, 'request rejected'); + assert.equal(reason, error, 'error is what we expect'); + }).then(function () { + restore(); + done(); + }); + }); + QUnit.test('async should be always true #51', function (assert) { + var done = assert.async(); + var headers = {}, restore = makeFixture(function () { + this.open = function (type, url, async) { + assert.ok(async); + }; + this.send = function () { + this.readyState = 4; + this.status = 204; + this.responseText = ''; + this.onreadystatechange(); + }; + this.setRequestHeader = function (header, value) { + headers[header] = value; + }; + }); + ajax({ + type: 'get', + url: '/ep' + }).then(function () { + restore(); + done(); + }); + }); + }(function () { + return this; + }(), '/', require, exports, module)); +}); +/*can-assign@1.3.3#can-assign-test*/ +define('can-assign@1.3.3#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 (assert) { + 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) { + assert.equal(expected[prop], actual[prop]); + } + }); + QUnit.test('Works with readonly properties', function (assert) { + 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' + }); + assert.equal(obj.a, 'a'); + assert.equal(obj.b, 'f'); + assert.equal(obj.c, 'c'); + assert.equal(obj.d, 'd'); + assign(obj, { c: 'h' }); + assert.equal(obj.a, 'a'); + assert.equal(obj.b, 'h'); + assert.equal(obj.c, 'c'); + assert.equal(obj.d, 'd'); + } catch (err) { + assert.ok(false, err); + } + }); +}); +/*can-bind@1.5.1#test/helpers*/ +define('can-bind@1.5.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.5.1#test/core*/ +define('can-bind@1.5.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', + 'can-queues' +], 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'); + var queues = require('can-queues'); + 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'); + }); + QUnit.test('use onEmit if observable has Symbol(\'can.onEmit\')', function (assert) { + var child = new SimpleObservable(5); + var parent = new SimpleObservable(1); + var childOffEmitCalled = false; + var childOnEmitCalled = false; + var setParentWasCalled = false; + var childEmitFn = null; + canReflect.assignSymbols(child, { + 'can.onEmit': function (updateFn) { + childOnEmitCalled = true; + childEmitFn = updateFn; + }, + 'can.offEmit': function () { + childOffEmitCalled = true; + }, + 'can.onValue': null + }); + var binding = new Bind({ + child: child, + parent: parent, + onInitDoNotUpdateParent: true, + childToParent: true, + parentToChild: false, + setParent: function (newValue) { + setParentWasCalled = true; + parent.set(newValue); + } + }); + binding.start(); + assert.equal(canReflect.getValue(parent), 1, 'has correct initial value'); + childEmitFn(5); + assert.equal(canReflect.getValue(parent), 5, 'has emitted value'); + assert.equal(childOnEmitCalled, true, 'onEmit was fired'); + assert.equal(setParentWasCalled, true, 'parent was updated'); + binding.stop(); + assert.equal(childOffEmitCalled, true, 'offEmit was fired'); + }); + if (queues.domQueue) { + QUnit.test('able to queue changes in dom queue', function (assert) { + var child = new SimpleObservable(5); + var parent = new SimpleObservable(1); + var element = document.createElement('div'); + var binding = new Bind({ + child: child, + parent: parent, + element: element, + queue: 'dom' + }); + binding.start(); + assert.equal(child.value, 1, 'updated child'); + }); + } +}); +/*can-bind@1.5.1#test/cycles-and-sticky*/ +define('can-bind@1.5.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, assert) { + 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 debugName = options.debugName; + var binding = new Bind({ + child: child, + cycles: cycles, + onInitDoNotUpdateChild: true, + parent: parent, + sticky: sticky, + debugName: debugName + }); + 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'); + } + assert.equal(canReflect.getValue(parent), expectedParent, 'parent updates'); + assert.equal(canReflect.getValue(child), expectedChild, 'child updates'); + binding.stop(); + } + QUnit.test('cyclical two-way binding - 0 cycles not sticky', function (assert) { + 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 + }, assert); + }); + canTestHelpers.dev.devOnlyTest('cyclical two-way binding - 0 cycles not sticky - warning in dev', function (assert) { + 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 + }, assert); + assert.equal(teardown(), 1, 'warning shown'); + }); + QUnit.test('cyclical two-way binding - 1 cycle not sticky', function (assert) { + 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 + }, assert); + }); + QUnit.test('cyclical two-way binding - 2 cycles not sticky', function (assert) { + 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 + }, assert); + }); + QUnit.test('two-way binding - 0 cycles childSticksToParent', function (assert) { + cycleStickyTest({ + parent: new SettableObservable(helpers.protectAgainstInfiniteLoops(helpers.incrementByOne), null, -1), + child: new SimpleObservable(0), + cycles: 0, + sticky: 'childSticksToParent', + startBySetting: 'child', + expectedParent: 2, + expectedChild: 2 + }, assert); + }); + canTestHelpers.dev.devOnlyTest('warn when changing the value of a sticky binding child-side', function (assert) { + assert.expect(8); + var msg = /.* changing or converting its value when set.*/; + var teardown = canTestHelpers.dev.willWarn(msg, function (text, match) { + if (match) { + assert.ok(true, 'Correct warning generated'); + } + }); + var parent = new SimpleObservable(1); + var child = new SettableObservable(helpers.protectAgainstInfiniteLoops(function () { + return 0; + }), 0); + canReflect.setName(child.observation.func, 'Test Child Observable'); + cycleStickyTest({ + parent: parent, + child: child, + startBySetting: 'parent', + sticky: 'childSticksToParent', + expectedParent: 1, + expectedChild: 0 + }, assert); + assert.equal(teardown(), 1, 'Warning generated only once'); + var shortName = 'The test binding'; + teardown = canTestHelpers.dev.willWarn(msg, function (text, match) { + if (match) { + assert.ok(true, 'Correct warning generated'); + } + }); + cycleStickyTest({ + parent: parent, + child: child, + startBySetting: 'parent', + sticky: 'childSticksToParent', + expectedParent: 1, + expectedChild: 0, + debugName: shortName + }, assert); + assert.equal(teardown(), 1, 'Warning generated only once'); + }); +}); +/*can-bind@1.5.1#test/detection*/ +define('can-bind@1.5.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.5.1#test/initialization*/ +define('can-bind@1.5.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, assert) { + var child = new SimpleObservable(options.startingChild); + var parent = new SimpleObservable(options.startingParent); + var binding = new Bind({ + child: child, + childToParent: options.childToParent, + onInitDoNotUpdateChild: options.onInitDoNotUpdateChild, + onInitDoNotUpdateParent: options.onInitDoNotUpdateParent, + onInitSetUndefinedParentIfChildIsDefined: options.onInitSetUndefinedParentIfChildIsDefined, + parent: parent, + parentToChild: options.parentToChild + }); + binding.start(); + assert.equal(canReflect.getValue(child), options.expectedChild, 'child value is correct'); + assert.equal(canReflect.getValue(parent), options.expectedParent, 'parent value is correct'); + binding.stop(); + } + QUnit.test('child=1 <-> parent=2 => child=2 parent=2', function (assert) { + initializationTest({ + startingChild: 1, + startingParent: 2, + childToParent: true, + parentToChild: true, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 2, + expectedParent: 2 + }, assert); + }); + QUnit.test('child=1 <-> parent=undefined => child=1 parent=1', function (assert) { + initializationTest({ + startingChild: 1, + startingParent: undefined, + childToParent: true, + parentToChild: true, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 1, + expectedParent: 1 + }, assert); + }); + QUnit.test('child=undefined <-> parent=2 => child=2 parent=2', function (assert) { + initializationTest({ + startingChild: undefined, + startingParent: 2, + childToParent: true, + parentToChild: true, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 2, + expectedParent: 2 + }, assert); + }); + QUnit.test('child=undefined <-> parent=undefined => child=undefined parent=undefined', function (assert) { + initializationTest({ + startingChild: undefined, + startingParent: undefined, + childToParent: true, + parentToChild: true, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: undefined, + expectedParent: undefined + }, assert); + }); + QUnit.test('child=3 <-> parent=3 => child=3 parent=3', function (assert) { + initializationTest({ + startingChild: 3, + startingParent: 3, + childToParent: true, + parentToChild: true, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 3, + expectedParent: 3 + }, assert); + }); + QUnit.test('child=1 -> parent=2 => child=1 parent=1', function (assert) { + initializationTest({ + startingChild: 1, + startingParent: 2, + childToParent: true, + parentToChild: false, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 1, + expectedParent: 1 + }, assert); + }); + QUnit.test('child=1 -> parent=undefined => child=1 parent=1', function (assert) { + initializationTest({ + startingChild: 1, + startingParent: undefined, + childToParent: true, + parentToChild: false, + onInitDoNotUpdateChild: false, + onInitDoNotUpdateParent: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 1, + expectedParent: 1 + }, assert); + }); + QUnit.test('child=1 -> parent=undefined => child=1 parent=undefined', function (assert) { + initializationTest({ + startingChild: 1, + startingParent: undefined, + childToParent: true, + parentToChild: false, + onInitDoNotUpdateChild: false, + onInitDoNotUpdateParent: true, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 1, + expectedParent: undefined + }, assert); + }); + QUnit.test('child=undefined -> parent=2 => child=undefined parent=undefined', function (assert) { + initializationTest({ + startingChild: undefined, + startingParent: 2, + childToParent: true, + parentToChild: false, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: undefined, + expectedParent: undefined + }, assert); + }); + QUnit.test('child=undefined -> parent=undefined => child=undefined parent=undefined', function (assert) { + initializationTest({ + startingChild: undefined, + startingParent: undefined, + childToParent: true, + parentToChild: false, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: undefined, + expectedParent: undefined + }, assert); + }); + QUnit.test('child=3 -> parent=3 => child=3 parent=3', function (assert) { + initializationTest({ + startingChild: 3, + startingParent: 3, + childToParent: true, + parentToChild: false, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 3, + expectedParent: 3 + }, assert); + }); + QUnit.test('child=1 <- parent=2 => child=2 parent=2', function (assert) { + initializationTest({ + startingChild: 1, + startingParent: 2, + childToParent: false, + parentToChild: true, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 2, + expectedParent: 2 + }, assert); + }); + QUnit.test('child=1 <- parent=undefined => child=undefined parent=undefined', function (assert) { + initializationTest({ + startingChild: 1, + startingParent: undefined, + childToParent: false, + parentToChild: true, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: undefined, + expectedParent: undefined + }, assert); + }); + QUnit.test('child=undefined <- parent=2 => child=2 parent=2', function (assert) { + initializationTest({ + startingChild: undefined, + startingParent: 2, + childToParent: false, + parentToChild: true, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 2, + expectedParent: 2 + }, assert); + }); + QUnit.test('child=undefined <- parent=undefined => child=undefined parent=undefined', function (assert) { + initializationTest({ + startingChild: undefined, + startingParent: undefined, + childToParent: false, + parentToChild: true, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: undefined, + expectedParent: undefined + }, assert); + }); + QUnit.test('child=3 <- parent=3 => child=3 parent=3', function (assert) { + initializationTest({ + startingChild: 3, + startingParent: 3, + childToParent: false, + parentToChild: true, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 3, + expectedParent: 3 + }, assert); + }); + QUnit.test('child=1 <-> parent=2 => child=1 parent=2 [onInitDoNotUpdateChild=true]', function (assert) { + initializationTest({ + startingChild: 1, + startingParent: 2, + childToParent: true, + parentToChild: true, + onInitDoNotUpdateChild: true, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 1, + expectedParent: 2 + }, assert); + }); + QUnit.test('child=1 <-> parent=undefined => child=1 parent=1 [onInitDoNotUpdateChild=true]', function (assert) { + initializationTest({ + startingChild: 1, + startingParent: undefined, + childToParent: true, + parentToChild: true, + onInitDoNotUpdateChild: true, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 1, + expectedParent: 1 + }, assert); + }); + QUnit.test('child=undefined <-> parent=2 => child=undefined parent=2 [onInitDoNotUpdateChild=true]', function (assert) { + initializationTest({ + startingChild: undefined, + startingParent: 2, + childToParent: true, + parentToChild: true, + onInitDoNotUpdateChild: true, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: undefined, + expectedParent: 2 + }, assert); + }); + QUnit.test('child=undefined <-> parent=undefined => child=undefined parent=undefined [onInitDoNotUpdateChild=true]', function (assert) { + initializationTest({ + startingChild: undefined, + startingParent: undefined, + childToParent: true, + parentToChild: true, + onInitDoNotUpdateChild: true, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: undefined, + expectedParent: undefined + }, assert); + }); + QUnit.test('child=3 <-> parent=3 => child=3 parent=3 [onInitDoNotUpdateChild=true]', function (assert) { + initializationTest({ + startingChild: 3, + startingParent: 3, + childToParent: true, + parentToChild: true, + onInitDoNotUpdateChild: true, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 3, + expectedParent: 3 + }, assert); + }); + QUnit.test('child=1 <- parent=2 => child=1 parent=2 [onInitDoNotUpdateChild=true]', function (assert) { + initializationTest({ + startingChild: 1, + startingParent: 2, + childToParent: false, + parentToChild: true, + onInitDoNotUpdateChild: true, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 1, + expectedParent: 2 + }, assert); + }); + QUnit.test('child=1 <- parent=undefined => child=1 parent=undefined [onInitDoNotUpdateChild=true]', function (assert) { + initializationTest({ + startingChild: 1, + startingParent: undefined, + childToParent: false, + parentToChild: true, + onInitDoNotUpdateChild: true, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 1, + expectedParent: undefined + }, assert); + }); + QUnit.test('child=undefined <- parent=2 => child=undefined parent=2 [onInitDoNotUpdateChild=true]', function (assert) { + initializationTest({ + startingChild: undefined, + startingParent: 2, + childToParent: false, + parentToChild: true, + onInitDoNotUpdateChild: true, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: undefined, + expectedParent: 2 + }, assert); + }); + QUnit.test('child=undefined <- parent=undefined => child=undefined parent=undefined [onInitDoNotUpdateChild=true]', function (assert) { + initializationTest({ + startingChild: undefined, + startingParent: undefined, + childToParent: false, + parentToChild: true, + onInitDoNotUpdateChild: true, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: undefined, + expectedParent: undefined + }, assert); + }); + QUnit.test('child=3 <- parent=3 => child=3 parent=3 [onInitDoNotUpdateChild=true]', function (assert) { + initializationTest({ + startingChild: 3, + startingParent: 3, + childToParent: false, + parentToChild: true, + onInitDoNotUpdateChild: true, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 3, + expectedParent: 3 + }, assert); + }); + QUnit.test('parent and child properties', 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 + }); + assert.equal(binding.child, child, 'child'); + assert.equal(binding.parent, parent, 'child'); + }); +}); +/*can-bind@1.5.1#test/test*/ +define('can-bind@1.5.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.6#can-construct_test*/ +define('can-construct@3.5.6#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', { + beforeEach: function (assert) { + 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; + } + }); + } + }); + QUnit.test('inherit', function (assert) { + var Base = Construct({}); + assert.ok(new Base() instanceof Construct); + var Inherit = Base({}); + assert.ok(new Inherit() instanceof Base); + }); + QUnit.test('Creating', function (assert) { + new this.Dog(); + var a1 = new this.Animal(); + new this.Animal(); + var ajax = new this.Ajax(1000); + assert.equal(2, this.Animal.count, 'right number of animals'); + assert.equal(1, this.Dog.count, 'right number of animals'); + assert.ok(this.Dog.match, 'right number of animals'); + assert.ok(!this.Animal.match, 'right number of animals'); + assert.ok(this.Dog.test(), 'right number of animals'); + assert.ok(!this.Animal.test(), 'right number of animals'); + assert.equal(1, this.Ajax.count, 'right number of animals'); + assert.equal(2, this.Animal.count, 'right number of animals'); + assert.equal(true, ajax.eyes, 'right number of animals'); + assert.equal(1000, ajax.hairs, 'right number of animals'); + assert.ok(a1 instanceof this.Animal); + assert.ok(a1 instanceof Construct); + }); + QUnit.test('new instance', function (assert) { + var d = this.Ajax.newInstance(6); + assert.equal(6, d.hairs); + }); + QUnit.test('namespaces', function (assert) { + var fb = Construct.extend('Bar'); + assert.ok(!window.Bar, 'not added to global namespace'); + if (Object.getOwnPropertyDescriptor) { + assert.equal(fb.name, 'Bar', 'name is right'); + } + assert.equal(fb.shortName, 'Bar', 'short name is right'); + }); + QUnit.test('setups', function (assert) { + 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'); + assert.equal(staticSetup, 1); + assert.equal(staticInit, 2); + assert.equal(protoSetup, 3); + assert.equal(protoInit, 4); + assert.deepEqual(Array.prototype.slice.call(staticInitArgs), ['something']); + assert.deepEqual(Array.prototype.slice.call(protoInitArgs), ['Ford: geo']); + assert.deepEqual(Array.prototype.slice.call(staticSetupArgs), [ + Construct, + 'Car', + staticProps, + protoProps + ], 'static construct'); + Car.extend('Truck'); + assert.equal(staticSetup, 5, 'Static setup is called if overwriting'); + }); + QUnit.test('Creating without extend', function (assert) { + var Bar = Construct('Bar', { + ok: function () { + assert.ok(true, 'ok called'); + } + }); + new Bar().ok(); + var Foo = Bar('Foo', { + dude: function () { + assert.ok(true, 'dude called'); + } + }); + new Foo().dude(true); + }); + QUnit.test('setup called with original arguments', function (assert) { + var o2 = {}; + var o1 = { + setup: function (base, arg1, arg2) { + assert.equal(o1, arg1, 'first argument is correct'); + assert.equal(o2, arg2, 'second argument is correct'); + } + }; + Construct.extend(o1, o2); + }); + QUnit.test('legacy namespace strings (A.B.C) accepted', function (assert) { + var Type = Construct.extend('Foo.Bar.Baz'); + var expectedValue = ~steal.config('env').indexOf('production') ? '' : 'Foo_Bar_Baz'; + assert.ok(new Type() instanceof Construct, 'No unexpected behavior in the prototype chain'); + if (Function.prototype.name) { + assert.equal(Type.name, expectedValue, 'Name becomes underscored'); + } + }); + QUnit.test('reserved words accepted', function (assert) { + var Type = Construct.extend('const'); + var expectedValue = ~steal.config('env').indexOf('production') ? '' : 'Const'; + assert.ok(new Type() instanceof Construct, 'No unexpected behavior in the prototype chain'); + if (Function.prototype.name) { + assert.equal(Type.name, expectedValue, 'Name becomes capitalized'); + } + }); + QUnit.test('basic injection attacks thwarted', function (assert) { + 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 { + assert.equal(rootObject[expando], undefined, 'Injected code doesn\'t run'); + } + delete rootObject[expando]; + try { + MalignantType = Construct.extend('(){},' + rootToken + '.' + expando + '=\'baz\',function'); + } catch (e) { + } finally { + assert.equal(rootObject[expando], undefined, 'Injected code doesn\'t run'); + } + }); + QUnit.test('setters not invoked on extension (#28)', function (assert) { + var extending = true; + var Base = Construct.extend('Base', { + set something(value) { + assert.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 (assert) { + var Alternative = function () { + }; + var Base = Construct.extend({ + setup: function () { + return new Construct.ReturnValue(new Alternative()); + } + }); + assert.ok(new Base() instanceof Alternative, 'Should create an instance of Alternative'); + }); + QUnit.test('return alternative value on setup (full case)', function (assert) { + 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; + } + }); + assert.equal(new Person({ age: 12 }).isStudent, false, 'Age 12 cannot be a student'); + assert.equal(new Person({ age: 30 }).isStudent, true, 'Age 20 can be a student'); + assert.ok(new Person({ age: 30 }) instanceof Student, 'Should return an instance of Student'); + }); + QUnit.test('extends defaults right', function (assert) { + var BASE = Construct.extend({ defaults: { foo: 'bar' } }, {}); + var INHERIT = BASE.extend({ defaults: { newProp: 'newVal' } }, {}); + assert.ok(INHERIT.defaults.foo === 'bar', 'Class must inherit defaults from the parent class'); + assert.ok(INHERIT.defaults.newProp === 'newVal', 'Class must have own defaults'); + }); + QUnit.test('enumerability', function (assert) { + var Parent = Construct.extend('Parent', {}); + var child = new Parent(); + child.foo = 'bar'; + var props = {}; + for (var prop in child) { + props[prop] = true; + } + assert.deepEqual(props, { foo: true }, 'only has ownProps'); + }); + QUnit.test('Has default init, setup functions', function (assert) { + var instance = new Construct(); + assert.equal(typeof instance.init, 'function', 'has init'); + assert.equal(typeof instance.setup, 'function', 'has setup'); + }); + QUnit.test('Extending should not update defaults nested objects', function (assert) { + var Parent = Construct.extend({ defaults: { obj: { foo: 'Bar' } } }, {}); + var Child = Parent.extend({ defaults: { obj: { foo: 'Baz' } } }, {}); + assert.equal(Parent.defaults.obj.foo, 'Bar', 'Base defaults are not changed'); + assert.equal(Child.defaults.obj.foo, 'Baz', 'Child defaults get defaults right'); + }); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-construct-super@3.2.1#can-construct-super*/ +define('can-construct-super@3.2.1#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.1#test/can-construct-super_test*/ +define('can-construct-super@3.2.1#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'); + QUnit.test('prototype super', function (assert) { + 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); + assert.equal(b.arg, 4); + assert.equal(b.add(2), 7); + }); + QUnit.test('static super', function (assert) { + var First = Construct.extend({ + raise: function (num) { + return num; + } + }, {}); + var Second = First.extend({ + raise: function (num) { + return this._super(num) * num; + } + }, {}); + assert.equal(Second.raise(2), 4); + }); + QUnit.test('findAll super', function (assert) { + var Parent = Construct.extend({ + findAll: function () { + assert.equal(this.shortName, 'child'); + return Promise.resolve(); + }, + shortName: 'parent' + }, {}); + var Child = Parent.extend({ + findAll: function () { + return this._super(); + }, + shortName: 'child' + }, {}); + var done = assert.async(); + assert.expect(1); + Child.findAll({}); + done(); + }); + if (Object.getOwnPropertyDescriptor) { + QUnit.test('_super supports getters and setters', function (assert) { + 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; + assert.equal(test.age, 50, 'Getter and _super works'); + test.name = 'David'; + assert.equal(test.name, 'David_super', 'Setter ran'); + }); + } + QUnit.test('setters not invoked on extension (#9)', function (assert) { + var extending = true; + var Base = Construct.extend('Base', { + set something(value) { + assert.ok(!extending, 'set not called when not extending'); + }, + get something() { + assert.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 (assert) { + var Parent = Construct.extend({}); + var Child = Parent.extend({ + init: function () { + this._super(); + assert.ok(true); + } + }); + new Child(); + }); + QUnit.test('_super should work for sealed instances', function (assert) { + 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); + assert.equal(b.arg, 4, 'should instantiate properly'); + assert.equal(b.add(2), 7, 'should call methods properly'); + }); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-control@4.4.3#can-control_test*/ +define('can-control@4.4.3#can-control_test', [ + 'require', + 'exports', + 'module', + 'can-control', + 'steal-qunit', + 'can-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-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', { + beforeEach: function (assert) { + this.fixture = document.getElementById('qunit-fixture'); + } + }); + QUnit.test('parameterized actions', function (assert) { + 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'); + assert.ok(called, 'heard the trigger'); + }); + QUnit.test('windowresize', function (assert) { + var called = false, WindowBind = Control.extend('', { + '{window} resize': function () { + called = true; + } + }); + this.fixture.appendChild(fragment('
      ')); + new WindowBind('#weird'); + domEvents.dispatch(window, 'resize'); + assert.ok(called, 'got window resize event'); + }); + QUnit.test('on', function (assert) { + assert.expect(9); + var called = false, DelegateTest = Control.extend({ + click: function () { + } + }), Tester = Control.extend({ + init: function (el, ops) { + this.on(window, 'click', function (ev) { + assert.ok(true, 'Got window click event'); + }); + this.on(window, 'click', 'clicked'); + this.on('click', function () { + assert.ok(true, 'Directly clicked element'); + }); + this.on('click', 'clicked'); + }, + clicked: function (context) { + assert.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'); + assert.ok(called, 'delegate works'); + domMutateNode.removeChild.call(this.fixture, document.querySelector('#els')); + domEvents.dispatch(div, 'click'); + domEvents.dispatch(window, 'click'); + rb.destroy(); + }); + QUnit.test('inherit', function (assert) { + 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'); + assert.ok(called, 'inherited the click method'); + }); + QUnit.test('space makes event', function (assert) { + assert.expect(1); + var Dot = Control.extend({ + ' foo': function () { + assert.ok(true, 'called'); + } + }); + this.fixture.appendChild(fragment('')); + new Dot('#els'); + domEvents.dispatch(document.querySelector('#els'), 'foo'); + }); + QUnit.test('custom events with hyphens work', function (assert) { + assert.expect(1); + this.fixture.appendChild(fragment('
      ')); + var FooBar = Control.extend({ + 'span custom-event': function () { + assert.ok(true, 'Custom event was fired.'); + } + }); + new FooBar('#customEvent'); + domEvents.dispatch(document.querySelector('#customEvent span'), 'custom-event'); + }); + QUnit.test('inherit defaults', function (assert) { + var BASE = Control.extend({ defaults: { foo: 'bar' } }, {}); + var INHERIT = BASE.extend({ defaults: { newProp: 'newVal' } }, {}); + assert.ok(INHERIT.defaults.foo === 'bar', 'Class must inherit defaults from the parent class'); + assert.ok(INHERIT.defaults.newProp === 'newVal', 'Class must have own defaults'); + var inst = new INHERIT(document.createElement('div'), {}); + assert.ok(inst.options.foo === 'bar', 'Instance must inherit defaults from the parent class'); + assert.ok(inst.options.newProp === 'newVal', 'Instance must have defaults of it`s class'); + }); + QUnit.test('on rebinding', function (assert) { + assert.expect(2); + var first = true; + var Rebinder = Control.extend({ + '{item} foo': function (item, ev) { + if (first) { + assert.equal(item.get('id'), 1, 'first item'); + first = false; + } else { + assert.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'); + }); + QUnit.test('actions provide method names', function (assert) { + var item1 = new SimpleMap({}); + var item2 = new SimpleMap({}); + var Tester = Control.extend({ + '{item1} foo': 'food', + '{item2} bar': 'food', + food: function (item, ev, data) { + assert.ok(true, 'food called'); + assert.ok(item === item1 || item === item2, 'called with an item'); + } + }); + new Tester(document.createElement('div'), { + item1: item1, + item2: item2 + }); + item1.dispatch('foo'); + item2.dispatch('bar'); + }); + QUnit.test('Don\'t bind if there are undefined values in templates', function (assert) { + var C = Control.extend({}, { + '{noExistStuff} proc': function () { + } + }); + var c = new C(document.createElement('div')); + assert.equal(c._bindings.user.length, 1, 'There is only one binding'); + var C2 = Control.extend({ + '{noExistStuff} click': function () { + assert.ok(false, 'should not fall through to click handler'); + } + }); + var div = document.createElement('div'); + new C2(div, {}); + domEvents.dispatch(div, 'click'); + }); + QUnit.test('Multiple calls to destroy', function (assert) { + assert.expect(2); + var C = Control.extend({ + destroy: function () { + assert.ok(true); + Control.prototype.destroy.call(this); + } + }), div = document.createElement('div'), c = new C(div); + c.destroy(); + c.destroy(); + }); + QUnit.test('drag and drop events', function (assert) { + assert.expect(7); + var DragDrop = Control.extend('', { + ' dragstart': function () { + assert.ok(true, 'dragstart called'); + }, + ' dragenter': function () { + assert.ok(true, 'dragenter called'); + }, + ' dragover': function () { + assert.ok(true, 'dragover called'); + }, + ' dragleave': function () { + assert.ok(true, 'dragleave called'); + }, + ' drag': function () { + assert.ok(true, 'drag called'); + }, + ' drop': function () { + assert.ok(true, 'drop called'); + }, + ' dragend': function () { + assert.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'); + }); + QUnit.test('beforeremove event', function (assert) { + assert.expect(1); + var Foo = Control.extend('', { + 'beforeremove': function () { + assert.ok(true, 'beforeremove called'); + } + }); + var el = fragment('
      '); + new Foo(el); + domEvents.dispatch(el, 'beforeremove'); + }); + if (System.env.indexOf('production') < 0) { + QUnit.test('Control is logging information in dev mode', function (assert) { + assert.expect(2); + var oldlog = dev.log; + var oldwarn = dev.warn; + dev.log = function (text) { + assert.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) { + assert.equal(text, 'can-control: Control already destroyed', 'control destroyed warning'); + }; + instance.destroy(); + instance.destroy(); + dev.warn = oldwarn; + dev.log = oldlog; + }); + } + QUnit.test('event handlers should rebind when target is replaced', function (assert) { + 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'); + assert.equal(nameChanges, 2); + }); + QUnit.test('{element} event handling', function (assert) { + assert.expect(3); + var done = assert.async(); + var MyControl = Control.extend({ + '{element} click': function (element) { + if (element === this.element) { + assert.ok(true, '`{element} click` should catch clicking on the element'); + } else { + assert.ok(true, '`{element} click` should catch clicking on a child of the element'); + } + }, + '{element} p click': function () { + assert.ok(true, '`{element} p click` works'); + done(); + } + }); + 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'); + }); + QUnit.test('Passing a Map as options works', function (assert) { + assert.expect(2); + var done = assert.async(); + var MyControl = Control.extend({ defaults: { testEndEvent: 'mouseleave' } }, { + '{element} {eventType}': function () { + assert.ok(true, 'catches handler from options'); + }, + '{element} {testEndEvent}': function () { + assert.ok(true, 'catches handler from defaults'); + done(); + } + }); + 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'); + }); + QUnit.test('Passing a DefineMap as options works', function (assert) { + assert.expect(2); + var done = assert.async(); + var MyControl = Control.extend({ defaults: { testEndEvent: 'mouseleave' } }, { + '{element} {eventType}': function () { + assert.ok(true, 'catches handler from options'); + }, + '{element} {testEndEvent}': function () { + assert.ok(true, 'catches handler from defaults'); + done(); + } + }); + 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'); + }); + QUnit.test('Creating an instance of a named control without passing an element', function (assert) { + var MyControl = Control.extend('MyControl'); + try { + new MyControl(); + } catch (e) { + assert.ok(true, 'Caught an exception'); + } + }); + QUnit.test('Creating an instance of a named control passing a selector', function (assert) { + this.fixture.appendChild(fragment('
      d
      ')); + var MyControl = Control.extend('MyControl'); + var myControlInstance = new MyControl('#my-control'); + assert.ok(myControlInstance.element.classList.contains('MyControl'), 'Element has the correct class name'); + }); + QUnit.test('can watch SimpleObservable', function (assert) { + var MyControl = Control.extend({ + '{simple}': function (simple, newVal) { + assert.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 (assert) { + var MyControl = Control.extend({}); + var div = document.createElement('div'); + var instance = new MyControl(div, {}); + assert.deepEqual(div[canSymbol.for('can.controls')], [instance], 'right instance'); + }); + QUnit.test('Able to handle the documentElement being removed', function (assert) { + var done = assert.async(); + 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); + assert.ok(true, 'it worked'); + done(); + }); + doc.removeChild(doc.documentElement); + }); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-define-lazy-value@1.1.1#define-lazy-value-test*/ +define('can-define-lazy-value@1.1.1#define-lazy-value-test', [ + 'steal-qunit@2.0.0#steal-qunit', + 'can-define-lazy-value@1.1.1#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 (assert) { + 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'); + assert.equal(obj2.id, 1, 'first object read should get id 1'); + assert.equal(obj1.id, 2, 'second object read should get id 2'); + try { + obj1.id = 3; + } catch (e) { + assert.ok(true, 'obj1.id should not be writable by default'); + } + (0, _canDefineLazyValue2.default)(MyObj.prototype, 'id', getId, true); + var obj3 = new MyObj('obj3'); + assert.equal(obj3.id, 3, 'obj3 should have id'); + obj3.id = 4; + assert.equal(obj3.id, 4, 'obj3.id should be writeable'); + }); +}); +/*can-deparam@1.2.1#can-deparam*/ +define('can-deparam@1.2.1#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.1#can-deparam-test*/ +define('can-deparam@1.2.1#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'); + QUnit.test('Nested deparam', function (assert) { + var data = deparam('a[b]=1&a[c]=2'); + assert.equal(data.a.b, 1); + assert.equal(data.a.c, 2); + data = deparam('a[]=1&a[]=2'); + assert.equal(data.a[0], 1); + assert.equal(data.a[1], 2); + data = deparam('a[b][]=1&a[b][]=2'); + assert.equal(data.a.b[0], 1); + assert.equal(data.a.b[1], 2); + data = deparam('a[0]=1&a[1]=2'); + assert.equal(data.a[0], 1); + assert.equal(data.a[1], 2); + }); + QUnit.test('Remaining ampersand', function (assert) { + var data = deparam('a[b]=1&a[c]=2&'); + assert.deepEqual(data, { + a: { + b: '1', + c: '2' + } + }); + }); + QUnit.test('Invalid encoding', function (assert) { + var data = deparam('foo=%0g'); + assert.deepEqual(data, { foo: '%0g' }); + }); + QUnit.test('deparam deep', function (assert) { + assert.deepEqual(deparam('age[or][][lte]=5&age[or][]=null'), { + age: { + or: [ + { lte: '5' }, + 'null' + ] + } + }); + }); + QUnit.test('takes value deserializer', function (assert) { + assert.deepEqual(deparam('age[or][][lte]=5&age[or][]=null', stringToAny), { + age: { + or: [ + { lte: 5 }, + null + ] + } + }); + assert.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.11#helpers/make-event-registry-test*/ +define('can-dom-events@1.3.11#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.11#helpers/add-event-compat*/ +define('can-dom-events@1.3.11#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.11#helpers/add-event-compat-test*/ +define('can-dom-events@1.3.11#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.5.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 getProto = Object.getPrototypeOf; + var slice = arr.slice; + var flat = arr.flat ? function (array) { + return arr.flat.call(array); + } : function (array) { + return arr.concat.apply([], array); + }; + 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 document = window.document; + var preservedScriptAttributes = { + type: true, + src: true, + nonce: true, + noModule: true + }; + function DOMEval(code, node, doc) { + doc = doc || document; + var i, val, script = doc.createElement('script'); + script.text = code; + if (node) { + for (i in preservedScriptAttributes) { + val = node[i] || node.getAttribute && node.getAttribute(i); + if (val) { + script.setAttribute(i, val); + } + } + } + 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.5.1', jQuery = function (selector, context) { + return new jQuery.fn.init(selector, context); + }; + 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); + }, + even: function () { + return this.pushStack(jQuery.grep(this, function (_elem, i) { + return (i + 1) % 2; + })); + }, + odd: function () { + return this.pushStack(jQuery.grep(this, function (_elem, i) { + return i % 2; + })); + }, + 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) { + copy = options[name]; + if (name === '__proto__' || target === copy) { + continue; + } + if (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = Array.isArray(copy)))) { + src = target[name]; + if (copyIsArray && !Array.isArray(src)) { + clone = []; + } else if (!copyIsArray && !jQuery.isPlainObject(src)) { + clone = {}; + } else { + clone = src; + } + copyIsArray = false; + 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, options, doc) { + DOMEval(code, { nonce: options && options.nonce }, doc); + }, + 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; + }, + 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 flat(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(), nonnativeSelectorCache = createCache(), sortOrder = function (a, b) { + if (a === b) { + hasDuplicate = true; + } + return 0; + }, hasOwn = {}.hasOwnProperty, arr = [], pop = arr.pop, pushNative = 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 = '(?:\\\\[\\da-fA-F]{1,6}' + whitespace + '?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+', 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 + '*'), rdescend = new RegExp(whitespace + '|>'), 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') + }, rhtml = /HTML$/i, rinputs = /^(?:input|select|textarea|button)$/i, rheader = /^h\d$/i, rnative = /^[^{]+\{\s*\[native \w/, rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, rsibling = /[+~]/, runescape = new RegExp('\\\\[\\da-fA-F]{1,6}' + whitespace + '?|\\\\([^\\r\\n\\f])', 'g'), funescape = function (escape, nonHex) { + var high = '0x' + escape.slice(1) - 65536; + return nonHex ? nonHex : 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(); + }, inDisabledFieldset = addCombinator(function (elem) { + return elem.disabled === true && elem.nodeName.toLowerCase() === 'fieldset'; + }, { + 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) { + pushNative.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) { + 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 && !nonnativeSelectorCache[selector + ' '] && (!rbuggyQSA || !rbuggyQSA.test(selector)) && (nodeType !== 1 || context.nodeName.toLowerCase() !== 'object')) { + newSelector = selector; + newContext = context; + if (nodeType === 1 && (rdescend.test(selector) || rcombinators.test(selector))) { + newContext = rsibling.test(selector) && testContext(context.parentNode) || context; + if (newContext !== context || !support.scope) { + 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 ? '#' + nid : ':scope') + ' ' + toSelector(groups[i]); + } + newSelector = groups.join(','); + } + try { + push.apply(results, newContext.querySelectorAll(newSelector)); + return results; + } catch (qsaError) { + nonnativeSelectorCache(selector, true); + } 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 && inDisabledFieldset(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 namespace = elem.namespaceURI, docElem = (elem.ownerDocument || elem).documentElement; + return !rhtml.test(namespace || docElem && docElem.nodeName || 'HTML'); + }; + 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.scope = assert(function (el) { + docElem.appendChild(el).appendChild(document.createElement('div')); + return typeof el.querySelectorAll !== 'undefined' && !el.querySelectorAll(':scope fieldset div').length; + }); + 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) { + var input; + 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('~='); + } + input = document.createElement('input'); + input.setAttribute('name', ''); + el.appendChild(input); + if (!el.querySelectorAll('[name=\'\']').length) { + rbuggyQSA.push('\\[' + whitespace + '*name' + whitespace + '*=' + whitespace + '*(?:\'\'|"")'); + } + if (!el.querySelectorAll(':checked').length) { + rbuggyQSA.push(':checked'); + } + if (!el.querySelectorAll('a#' + expando + '+*').length) { + rbuggyQSA.push('.#.+[+~]'); + } + el.querySelectorAll('\\\f'); + rbuggyQSA.push('[\\r\\n\\f]'); + }); + 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) { + setDocument(elem); + if (support.matchesSelector && documentIsHTML && !nonnativeSelectorCache[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) { + nonnativeSelectorCache(expr, true); + } + } + 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 || 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 > length ? 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 (elem.contentDocument != null && getProto(elem.contentDocument)) { + 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 documentElement = document.documentElement; + var isAttached = function (elem) { + return jQuery.contains(elem.ownerDocument, elem); + }, composed = { composed: true }; + if (documentElement.getRootNode) { + isAttached = function (elem) { + return jQuery.contains(elem.ownerDocument, elem) || elem.getRootNode(composed) === elem.ownerDocument; + }; + } + var isHiddenWithinTree = function (elem, el) { + elem = el || elem; + return elem.style.display === 'none' || elem.style.display === '' && isAttached(elem) && jQuery.css(elem, 'display') === 'none'; + }; + 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 = elem.nodeType && (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; + (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; + div.innerHTML = ''; + support.option = !!div.lastChild; + }()); + var wrapMap = { + thead: [ + 1, + '', + '
      ' + ], + col: [ + 2, + '', + '
      ' + ], + tr: [ + 2, + '', + '
      ' + ], + td: [ + 3, + '', + '
      ' + ], + _default: [ + 0, + '', + '' + ] + }; + wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; + wrapMap.th = wrapMap.td; + if (!support.option) { + wrapMap.optgroup = wrapMap.option = [ + 1, + '' + ]; + } + 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, attached, 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; + } + attached = isAttached(elem); + tmp = getAll(fragment.appendChild(elem), 'script'); + if (attached) { + setGlobalEval(tmp); + } + if (scripts) { + j = 0; + while (elem = tmp[j++]) { + if (rscriptType.test(elem.type || '')) { + scripts.push(elem); + } + } + } + } + return fragment; + } + var rkeyEvent = /^key/, rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + function returnTrue() { + return true; + } + function returnFalse() { + return false; + } + function expectSync(elem, type) { + return elem === safeActiveElement() === (type === 'focus'); + } + 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 (!acceptData(elem)) { + 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 = Object.create(null); + } + 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 i, j, ret, matched, handleObj, handlerQueue, args = new Array(arguments.length), event = jQuery.event.fix(nativeEvent), handlers = (dataPriv.get(this, 'events') || Object.create(null))[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 || handleObj.namespace === false || 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 }, + click: { + setup: function (data) { + var el = this || data; + if (rcheckableType.test(el.type) && el.click && nodeName(el, 'input')) { + leverageNative(el, 'click', returnTrue); + } + return false; + }, + trigger: function (data) { + var el = this || data; + if (rcheckableType.test(el.type) && el.click && nodeName(el, 'input')) { + leverageNative(el, 'click'); + } + return true; + }, + _default: function (event) { + var target = event.target; + return rcheckableType.test(target.type) && target.click && nodeName(target, 'input') && dataPriv.get(target, 'click') || nodeName(target, 'a'); + } + }, + beforeunload: { + postDispatch: function (event) { + if (event.result !== undefined && event.originalEvent) { + event.originalEvent.returnValue = event.result; + } + } + } + } + }; + function leverageNative(el, type, expectSync) { + if (!expectSync) { + if (dataPriv.get(el, type) === undefined) { + jQuery.event.add(el, type, returnTrue); + } + return; + } + dataPriv.set(el, type, false); + jQuery.event.add(el, type, { + namespace: false, + handler: function (event) { + var notAsync, result, saved = dataPriv.get(this, type); + if (event.isTrigger & 1 && this[type]) { + if (!saved.length) { + saved = slice.call(arguments); + dataPriv.set(this, type, saved); + notAsync = expectSync(this, type); + this[type](); + result = dataPriv.get(this, type); + if (saved !== result || notAsync) { + dataPriv.set(this, type, false); + } else { + result = {}; + } + if (saved !== result) { + event.stopImmediatePropagation(); + event.preventDefault(); + return result.value; + } + } else if ((jQuery.event.special[type] || {}).delegateType) { + event.stopPropagation(); + } + } else if (saved.length) { + dataPriv.set(this, type, { value: jQuery.event.trigger(jQuery.extend(saved[0], jQuery.Event.prototype), saved.slice(1), this) }); + event.stopImmediatePropagation(); + } + } + }); + } + 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, + code: 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({ + focus: 'focusin', + blur: 'focusout' + }, function (type, delegateType) { + jQuery.event.special[type] = { + setup: function () { + leverageNative(this, type, expectSync); + return false; + }, + trigger: function () { + leverageNative(this, type); + return true; + }, + delegateType: delegateType + }; + }); + 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 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, udataOld, udataCur, events; + if (dest.nodeType !== 1) { + return; + } + if (dataPriv.hasData(src)) { + pdataOld = dataPriv.get(src); + events = pdataOld.events; + if (events) { + dataPriv.remove(dest, 'handle 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 = flat(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 && !node.noModule) { + jQuery._evalUrl(node.src, { nonce: node.nonce || node.getAttribute('nonce') }, doc); + } + } else { + DOMEval(node.textContent.replace(rcleanScript, ''), node, doc); + } + } + } + } + } + } + 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 && isAttached(node)) { + setGlobalEval(getAll(node, 'script')); + } + node.parentNode.removeChild(node); + } + } + return elem; + } + jQuery.extend({ + htmlPrefilter: function (html) { + return html; + }, + clone: function (elem, dataAndEvents, deepDataAndEvents) { + var i, l, srcElements, destElements, clone = elem.cloneNode(true), inPage = isAttached(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 swap = function (elem, options, callback) { + var ret, name, old = {}; + for (name in options) { + old[name] = elem.style[name]; + elem.style[name] = options[name]; + } + ret = callback.call(elem); + for (name in options) { + elem.style[name] = old[name]; + } + return ret; + }; + 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 = roundPixelMeasures(div.offsetWidth / 3) === 12; + documentElement.removeChild(container); + div = null; + } + function roundPixelMeasures(measure) { + return Math.round(parseFloat(measure)); + } + var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, reliableTrDimensionsVal, 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; + }, + reliableTrDimensions: function () { + var table, tr, trChild, trStyle; + if (reliableTrDimensionsVal == null) { + table = document.createElement('table'); + tr = document.createElement('tr'); + trChild = document.createElement('div'); + table.style.cssText = 'position:absolute;left:-11111px'; + tr.style.height = '1px'; + trChild.style.height = '9px'; + documentElement.appendChild(table).appendChild(tr).appendChild(trChild); + trStyle = window.getComputedStyle(tr); + reliableTrDimensionsVal = parseInt(trStyle.height) > 3; + documentElement.removeChild(table); + } + return reliableTrDimensionsVal; + } + }); + }()); + 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 === '' && !isAttached(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 cssPrefixes = [ + 'Webkit', + 'Moz', + 'ms' + ], emptyStyle = document.createElement('div').style, vendorProps = {}; + function vendorPropName(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 final = jQuery.cssProps[name] || vendorProps[name]; + if (final) { + return final; + } + if (name in emptyStyle) { + return name; + } + return vendorProps[name] = vendorPropName(name) || name; + } + var rdisplayswap = /^(none|table(?!-c[ea]).+)/, rcustomProp = /^--/, cssShow = { + position: 'absolute', + visibility: 'hidden', + display: 'block' + }, cssNormalTransform = { + letterSpacing: '0', + fontWeight: '400' + }; + 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)) || 0; + } + return delta; + } + function getWidthOrHeight(elem, dimension, extra) { + var styles = getStyles(elem), boxSizingNeeded = !support.boxSizingReliable() || extra, isBorderBox = boxSizingNeeded && jQuery.css(elem, 'boxSizing', false, styles) === 'border-box', valueIsBorderBox = isBorderBox, val = curCSS(elem, dimension, styles), offsetProp = 'offset' + dimension[0].toUpperCase() + dimension.slice(1); + if (rnumnonpx.test(val)) { + if (!extra) { + return val; + } + val = 'auto'; + } + if ((!support.boxSizingReliable() && isBorderBox || !support.reliableTrDimensions() && nodeName(elem, 'tr') || val === 'auto' || !parseFloat(val) && jQuery.css(elem, 'display', false, styles) === 'inline') && elem.getClientRects().length) { + isBorderBox = jQuery.css(elem, 'boxSizing', false, styles) === 'border-box'; + valueIsBorderBox = offsetProp in elem; + if (valueIsBorderBox) { + val = elem[offsetProp]; + } + } + 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, + 'gridArea': true, + 'gridColumn': true, + 'gridColumnEnd': true, + 'gridColumnStart': true, + 'gridRow': true, + 'gridRowEnd': true, + 'gridRowStart': 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' && !isCustomProp) { + 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), scrollboxSizeBuggy = !support.scrollboxSize() && styles.position === 'absolute', boxSizingNeeded = scrollboxSizeBuggy || extra, isBorderBox = boxSizingNeeded && jQuery.css(elem, 'boxSizing', false, styles) === 'border-box', subtract = extra ? boxModelAdjustment(elem, dimension, extra, isBorderBox, styles) : 0; + if (isBorderBox && scrollboxSizeBuggy) { + 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 && (jQuery.cssHooks[tween.prop] || tween.elem.style[finalPropName(tween.prop)] != null)) { + 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) { + 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') || Object.create(null))[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.document || 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.document || 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 = { guid: 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 (a == null) { + return ''; + } + 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() + ' '] = (responseHeaders[match[1].toLowerCase() + ' '] || []).concat(match[2]); + } + } + match = responseHeaders[key.toLowerCase() + ' ']; + } + return match == null ? null : match.join(', '); + }, + 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.guid++ + 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); + } + if (!isSuccess && jQuery.inArray('script', s.dataTypes) > -1) { + s.converters['text script'] = function () { + }; + } + 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.ajaxPrefilter(function (s) { + var i; + for (i in s.headers) { + if (i.toLowerCase() === 'content-type') { + s.contentType = s.headers[i] || ''; + } + } + }); + jQuery._evalUrl = function (url, options, doc) { + return jQuery.ajax({ + url: url, + type: 'GET', + dataType: 'script', + cache: true, + async: false, + global: false, + converters: { + 'text script': function () { + } + }, + dataFilter: function (response) { + jQuery.globalEval(response, options, doc); + } + }); + }; + 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 || s.scriptAttrs) { + 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.7.0#lib/default-tokenize*/ +define('can-simple-dom@1.7.0#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.7.0#test/element-sp-test*/ +define('can-simple-dom@1.7.0#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 (assert) { + var document = new Document(); + document.__addSerializerAndParser(new Serializer(voidMap), new Parser(tokenize, document, voidMap)); + assert.ok(document.implementation, 'implementation exists'); + var doc2 = document.implementation.createHTMLDocument(''); + assert.ok(doc2.body, 'has a body'); + }); + QUnit.test('innerHTML supported', function (assert) { + var document = new Document(); + document.__addSerializerAndParser(new Serializer(voidMap), new Parser(tokenize, document, voidMap)); + document.body.innerHTML = 'HI'; + assert.equal(document.body.firstChild.nodeName, 'SPAN'); + assert.equal(document.body.firstChild.className, 'bar'); + assert.equal(document.body.firstChild.firstChild.nodeValue, 'HI'); + assert.equal(document.body.innerHTML, 'HI'); + }); + QUnit.test('outerHTML supported', function (assert) { + var document = new Document(); + document.__addSerializerAndParser(new Serializer(voidMap), new Parser(tokenize, document, voidMap)); + document.body.innerHTML = '
      HI
      '; + var item = document.getElementById('item'); + assert.equal(item.outerHTML, '
      HI
      ', 'getter'); + item.outerHTML = ''; + assert.equal(document.body.innerHTML, '', 'setter'); + }); +}); +/*can-simple-dom@1.7.0#test/element-event-test*/ +define('can-simple-dom@1.7.0#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', function (assert) { + assert.expect(4); + 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', function (assert) { + assert.expect(2); + 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', function (assert) { + assert.expect(2); + 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.7.0#test/parser-test*/ +define('can-simple-dom@1.7.0#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.7.0#test/style-test*/ +define('can-simple-dom@1.7.0#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 (assert) { + var proto = CSSStyleDeclaration.prototype; + var descriptor = Object.getOwnPropertyDescriptor(proto, 'cssText'); + assert.equal(descriptor.enumerable, true, 'it is enumerable'); + }); + QUnit.test('cssText is configurable', function (assert) { + var proto = CSSStyleDeclaration.prototype; + var descriptor = Object.getOwnPropertyDescriptor(proto, 'cssText'); + assert.equal(descriptor.configurable, true, 'it is configurable'); + }); + QUnit.test('getPropertyValue must be a function', function (assert) { + var proto = CSSStyleDeclaration.prototype; + assert.equal(typeof proto.getPropertyValue, 'function', 'it is a function'); + }); +}); +/*can-simple-dom@1.7.0#test/test*/ +define('can-simple-dom@1.7.0#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.5.0#can-simple-observable-test*/ +define('can-simple-observable@2.5.0#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 (assert) { + assert.expect(5); + var obs = new SimpleObservable('one'); + assert.equal(canReflect.getValue(obs), 'one', 'getValue'); + canReflect.setValue(obs, 'two'); + ObservationRecorder.start(); + assert.equal(canReflect.getValue(obs), 'two', 'setValue'); + var dependencies = ObservationRecorder.stop(); + assert.ok(dependencies.valueDependencies.has(obs), 'was recorded'); + var handler = function (newValue) { + assert.equal(newValue, 'three', 'onValue'); + }; + canReflect.onValue(obs, handler); + canReflect.setValue(obs, 'three'); + canReflect.offValue(obs, handler); + canReflect.setValue(obs, 'four'); + assert.equal(canReflect.getValue(obs), 'four', 'getValue after offValue'); + }); + QUnit.test('basics with .value', function (assert) { + assert.expect(5); + var obs = new SimpleObservable('one'); + assert.equal(obs.value, 'one', 'getValue'); + obs.value = 'two'; + ObservationRecorder.start(); + assert.equal(obs.value, 'two', 'setValue'); + var dependencies = ObservationRecorder.stop(); + assert.ok(dependencies.valueDependencies.has(obs), 'was recorded'); + var handler = function (newValue) { + assert.equal(newValue, 'three', 'onValue'); + }; + canReflect.onValue(obs, handler); + obs.value = 'three'; + canReflect.offValue(obs, handler); + obs.value = 'four'; + assert.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.3#can-stache-key-test*/ +define('can-stache-key@1.4.3#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', {}); + QUnit.test('can read a promise (#179)', function (assert) { + var done = assert.async(); + 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++; + assert.equal(calls, 1, 'only one call'); + assert.equal(newVal, 'Something', 'new value'); + assert.equal(oldVal, undefined, 'oldVal'); + done(); + }); + }); + QUnit.test('can.Compute.read can read a promise-like (#82)', function (assert) { + var done = assert.async(); + 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++; + assert.equal(calls, 1, 'only one call'); + assert.equal(newVal, 'Something', 'new value'); + assert.equal(oldVal, undefined, 'oldVal'); + done(); + }); + }); + QUnit.test('can.compute.reads', function (assert) { + assert.deepEqual(observeReader.reads('@foo'), [{ + key: 'foo', + at: true + }]); + assert.deepEqual(observeReader.reads('@foo.bar'), [ + { + key: 'foo', + at: true + }, + { + key: 'bar', + at: false + } + ]); + assert.deepEqual(observeReader.reads('@foo\\.bar'), [{ + key: 'foo.bar', + at: true + }]); + assert.deepEqual(observeReader.reads('foo.bar@zed'), [ + { + key: 'foo', + at: false + }, + { + key: 'bar', + at: false + }, + { + key: 'zed', + at: true + } + ]); + }); + QUnit.test('able to read things like can-define', function (assert) { + assert.expect(3); + 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) { + assert.equal(obs, obj, 'got an observable'); + assert.equal(index, 1, 'got the right index'); + } + }).value; + assert.equal(value, 'PROP'); + }); + canReflect.onValue(c, function () { + }); + }); + QUnit.test('foundObservable called with observable object (#7)', function (assert) { + 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) { + assert.equal(obs, map); + }, + callMethodsOnObservables: true + }); + }); + canReflect.onValue(c, function () { + }); + }); + QUnit.test('can read from strings', function (assert) { + var context = ' hi there '; + var result = observeReader.read(context, observeReader.reads('trim'), {}); + assert.equal(result.value(context), context.trim(context), 'trim method works'); + }); + QUnit.test('read / write to SimpleMap', function (assert) { + var map = new SimpleMap(); + var c = new Observation(function () { + var data = observeReader.read(map, observeReader.reads('value'), { + foundObservable: function (obs) { + assert.equal(obs, map, 'got map'); + } + }); + return data.value; + }); + canReflect.onValue(c, function (newVal) { + assert.equal(newVal, 1, 'got updated'); + }); + observeReader.write(map, 'value', 1); + }); + QUnit.test('write deep in SimpleMap', function (assert) { + var map = new SimpleMap(); + observeReader.write(map, 'foo', new SimpleMap()); + observeReader.write(map, 'foo.bar', 1); + assert.equal(map.get('foo').get('bar'), 1, 'value set'); + }); + QUnit.test('write to compute in object', function (assert) { + 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); + assert.equal(value, 3, 'value set'); + }); + QUnit.test('write to a map in a compute', function (assert) { + 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); + assert.equal(map.attr('complete'), false, 'value set'); + }); + QUnit.test('reads can be passed a number (can-stache#207)', function (assert) { + var reads = observeReader.reads(0); + assert.deepEqual(reads, [{ + key: '0', + at: false + }], 'number converted to string'); + }); + QUnit.test('can read primitive numbers (#88)', function (assert) { + var reads = observeReader.reads('num@toFixed'); + var toFixed = observeReader.read({ num: 5 }, reads, {}).value; + assert.equal(typeof toFixed, 'function', 'got to fixed'); + }); + QUnit.test('it returns null when promise getter is null #2', function (assert) { + var nullPromise = observeReader.read(null, observeReader.reads('value')); + assert.equal(typeof nullPromise, 'object'); + }); + QUnit.test('set onto observable objects and values', function (assert) { + var map = new SimpleMap(); + observeReader.write({ map: map }, 'map', { a: 'b' }); + assert.equal(map.get('a'), 'b', 'merged'); + var simple = new SimpleObservable(); + observeReader.write({ simple: simple }, 'simple', 1); + assert.equal(simple.get(), 1); + }); + testHelpers.dev.devOnlyTest('functions are not called by read()', function (assert) { + var func = function () { + assert.ok(false, 'method called'); + }; + var data = { func: func }; + var reads = observeReader.reads('func'); + observeReader.read(data, reads); + assert.ok(true); + }); + testHelpers.dev.devOnlyTest('a warning is given for `callMethodsOnObservables: true`', function (assert) { + var teardown = testHelpers.dev.willWarn('can-stache-key: read() called with `callMethodsOnObservables: true`.'); + var func = function () { + assert.ok(true, 'method called'); + }; + var data = new SimpleMap({ func: func }); + var reads = observeReader.reads('func'); + observeReader.read(data, reads, { callMethodsOnObservables: true }); + assert.equal(teardown(), 1, 'warning displayed'); + }); + QUnit.test('writing to a null observable is ignored', function (assert) { + observeReader.write({}, 'foo.bar', 'value'); + observeReader.write(null, 'bar', 'value'); + observeReader.write(null, 'foo.bar', 'value'); + assert.ok(true, 'all passed without error'); + }); + QUnit.test('parentHasKey and foundLastParent (#31)', function (assert) { + 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]; + assert.equal(actual.value, expected.value, key + '.value'); + assert.equal(actual.parent, expected.parent, key + '.parent'); + assert.equal(actual.parentHasKey, expected.parentHasKey, key + '.parentHasKey'); + assert.equal(actual.foundLastParent, expected.foundLastParent, key + '.foundLastParent'); + } + }); + QUnit.test('objHasKeyAtIndex doesn\'t handle non-object types correctly (#33)', function (assert) { + var result = observeReader.read(47, observeReader.reads('toFixed')); + assert.equal(typeof result.value, 'function'); + assert.equal(result.parent, 47); + assert.equal(result.parentHasKey, true); + }); + QUnit.test('write to an object', function (assert) { + var obj = {}; + observeReader.write(obj, 'value', 1); + assert.deepEqual(obj, { value: 1 }); + obj = { value: null }; + observeReader.write(obj, 'value', 1); + assert.deepEqual(obj, { value: 1 }); + }); + QUnit.test('.then won\'t call bindings #49', function (assert) { + var promiseIsh = {}; + Object.defineProperty(promiseIsh, 'then', { + get: function () { + ObservationRecorder.add(this, 'then'); + } + }); + ObservationRecorder.start(); + observeReader.read(promiseIsh, observeReader.reads('prop')); + var recordings = ObservationRecorder.stop(); + assert.equal(recordings.keyDependencies.size, 0, 'no key recordings'); + }); +}); +/*can-validate-interface@1.0.3#index*/ +define('can-validate-interface@1.0.3#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.3#test*/ +define('can-validate-interface@1.0.3#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 (assert) { + 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); + assert.deepEqual(errors, { + message: 'missing expected properties', + related: ['id'] + }); + dao.id = 10; + errors = daoValidator(dao); + assert.equal(errors, undefined); + }); +}); +/*can-view-live@4.2.8#test/html-test*/ +define('can-view-live@4.2.8#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'); + QUnit.test('basics', function (assert) { + 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); + assert.equal(div.getElementsByTagName('label').length, 2); + items.push('three'); + assert.equal(div.getElementsByTagName('label').length, 3); + }); + QUnit.test('html live binding handles getting a function from a compute', function (assert) { + assert.expect(5); + var handler = function (el) { + assert.ok(true, 'called handler'); + assert.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); + assert.equal(div.getElementsByTagName('h1').length, 1, 'got h1'); + count.set(1); + assert.equal(div.getElementsByTagName('h1').length, 0, 'got h1'); + count.set(0); + assert.equal(div.getElementsByTagName('h1').length, 1, 'got h1'); + }); + QUnit.test('Works with Observations - .html', function (assert) { + 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); + assert.equal(div.getElementsByTagName('label').length, 2); + items.push('three'); + assert.equal(div.getElementsByTagName('label').length, 3); + }); + QUnit.test('html live binding handles objects with can.viewInsert symbol', function (assert) { + assert.expect(2); + 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', function (assert) { + assert.expect(1); + var observable = new SimpleObservable('value'); + var childObservation = new Observation(function child() { + assert.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 (assert) { + 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]; + assert.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 (assert) { + 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(); + assert.ok(true, 'got here without an error'); + assert.deepEqual(div.innerHTML.toLowerCase(), '

      3

      '); + }); +}); +/*can-view-live@4.2.8#lib/patcher*/ +define('can-view-live@4.2.8#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.8#test/patcher-test*/ +define('can-view-live@4.2.8#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', { + beforeEach: function () { + this.fixture = document.getElementById('qunit-fixture'); + } + }); + QUnit.test('multiple lists can be updated at once', function (assert) { + assert.expect(2); + var list = new DefineList([ + 'a', + 'b' + ]); + var p1 = new Patcher(list), p2 = new Patcher(list); + p1[canSymbol.for('can.onPatches')](function () { + assert.ok(true, 'called p1'); + }); + p2[canSymbol.for('can.onPatches')](function () { + assert.ok(true, 'called p2'); + }); + list.push('c'); + }); + QUnit.test('undefined value won\'t error', function (assert) { + assert.expect(1); + var undfinedObservable = new SimpleObservable(undefined); + var pu = new Patcher(undfinedObservable); + pu[canSymbol.for('can.onPatches')](function () { + assert.ok(true, 'called pu'); + }); + undfinedObservable.set('a'); + }); +}); +/*can-view-live@4.2.8#test/list-test*/ +define('can-view-live@4.2.8#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', { + beforeEach: function () { + this.fixture = document.getElementById('qunit-fixture'); + } + }); + QUnit.test('basics', function (assert) { + 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, {}); + assert.equal(div.getElementsByTagName('label').length, 2, 'There are 2 labels'); + div.getElementsByTagName('label')[0].myexpando = 'EXPANDO-ED'; + list.push('turtle'); + assert.equal(div.getElementsByTagName('label')[0].myexpando, 'EXPANDO-ED', 'same expando'); + assert.equal(div.getElementsByTagName('span')[2].innerHTML, 'turtle', 'turtle added'); + }); + QUnit.test('list within an Observation', function (assert) { + assert.expect(5); + 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, {}); + assert.equal(div.getElementsByTagName('label').length, 2, 'There are 2 labels'); + div.getElementsByTagName('label')[0].myexpando = 'EXPANDO-ED'; + map.attr('animals').push('turtle'); + assert.equal(div.getElementsByTagName('label')[0].myexpando, 'EXPANDO-ED', 'same expando'); + assert.equal(div.getElementsByTagName('span')[2].innerHTML, 'turtle', 'turtle added'); + map.attr('animals', new DefineList([ + 'sloth', + 'bear', + 'turtle' + ])); + var spans = div.getElementsByTagName('span'); + assert.equal(spans.length, 3, 'there are 3 spans'); + assert.ok(!div.getElementsByTagName('label')[0].myexpando, 'no expando'); + }); + QUnit.test('.list within a observable value holding an Array list', function (assert) { + 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, {}); + assert.equal(div.getElementsByTagName('label').length, 2, 'There are 2 labels'); + arr.set([ + 0, + 1, + 2 + ]); + var spans = div.getElementsByTagName('span'); + assert.equal(spans.length, 3, 'there are 3 spans'); + }); + QUnit.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; + }); + assert.deepEqual(values, [ + 'b', + 'a', + 'c' + ]); + }); + QUnit.test('list and an falsey section (#1979)', function (assert) { + 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); + assert.equal(div.getElementsByTagName('label').length, 2, 'There are 2 labels'); + listCompute.set([]); + var spans = div.getElementsByTagName('span'); + assert.equal(spans.length, 0, 'there are 0 spans'); + var ps = div.getElementsByTagName('p'); + assert.equal(ps.length, 1, 'there is 1 p'); + listCompute.set([2]); + spans = div.getElementsByTagName('span'); + assert.equal(spans.length, 1, 'there is 1 spans'); + ps = div.getElementsByTagName('p'); + assert.equal(ps.length, 0, 'there is 1 p'); + }); + QUnit.test('list and an initial falsey section (#1979)', function (assert) { + 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'); + assert.equal(spans.length, 0, 'there are 0 spans'); + var ps = div.getElementsByTagName('p'); + assert.equal(ps.length, 1, 'there is 1 p'); + listCompute.set([2]); + spans = div.getElementsByTagName('span'); + assert.equal(spans.length, 1, 'there is 1 spans'); + ps = div.getElementsByTagName('p'); + assert.equal(ps.length, 0, 'there is 1 p'); + }); + QUnit.test('list items should be correct even if renderer flushes batch (#8)', function (assert) { + 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, {}); + assert.equal(partial.getElementsByTagName('span').length, 2, 'should be two items'); + assert.equal(partial.getElementsByTagName('span')[0].firstChild.data, 'one', 'list item 0 is "one"'); + assert.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(); + assert.equal(partial.getElementsByTagName('span').length, 2, 'should be two items'); + assert.equal(partial.getElementsByTagName('span')[0].firstChild.data, 'three', 'list item 0 is "three"'); + assert.equal(partial.getElementsByTagName('span')[1].firstChild.data, 'one', 'list item 1 is "one"'); + }); + QUnit.test('changing items in a live.list after it has been unregistered works (#55)', function (assert) { + 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(); + assert.ok(true, 'should not throw'); + }); + QUnit.test('Works with Observations - .list', function (assert) { + 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, {}); + assert.equal(div.getElementsByTagName('label').length, 2, 'There are 2 labels'); + div.getElementsByTagName('label')[0].myexpando = 'EXPANDO-ED'; + map.attr('animals').push('turtle'); + assert.equal(div.getElementsByTagName('label')[0].myexpando, 'EXPANDO-ED', 'same expando'); + assert.equal(div.getElementsByTagName('span')[2].innerHTML, 'turtle', 'turtle added'); + map.attr('animals', new DefineList([ + 'sloth', + 'bear', + 'turtle' + ])); + var spans = div.getElementsByTagName('span'); + assert.equal(spans.length, 3, 'there are 3 spans'); + assert.ok(!div.getElementsByTagName('label')[0].myexpando, 'no expando'); + }); + QUnit.test('no memory leaks', function (assert) { + 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, {}); + var done = assert.async(); + function checkHandlers() { + var handlers = map[canSymbol.for('can.meta')].handlers.get([]); + if (handlers.length === 0) { + assert.equal(handlers.length, 0, 'there are no bindings'); + done(); + } 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); + }); + QUnit.test('no memory leaks with replacements (#93)', function (assert) { + 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); + assert.deepEqual(nodeList.replacements, [], 'no replacements'); + animals.push('foo'); + assert.deepEqual(nodeList.replacements, [], 'no replacements'); + animals.shift(); + assert.deepEqual(nodeList.replacements, [], 'no replacements'); + }); + QUnit.test('Undefined list and teardown', function (assert) { + 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, {}); + var done = assert.async(); + function checkHandlers() { + assert.ok(true, 'was able to teardown'); + done(); + } + setTimeout(function () { + domMutateNode.removeChild.call(fixture, div); + afterMutation(checkHandlers); + }, 10); + }); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-view-live@4.2.8#test/text-test*/ +define('can-view-live@4.2.8#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', { + beforeEach: function () { + this.fixture = document.getElementById('qunit-fixture'); + } + }); + var esc = function (str) { + return str.replace(//g, '>'); + }; + QUnit.test('text', function (assert) { + 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); + assert.equal(div.innerHTML, esc('')); + value.set([ + 'one', + 'two', + 'three' + ]); + assert.equal(div.innerHTML, esc('')); + }); + QUnit.test('text binding is memory safe (#666)', function (assert) { + 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); + var done = assert.async(); + setTimeout(function () { + assert.ok(!nodeLists.nodeMap.size, 'nothing in nodeMap'); + done(); + }, 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.8#test/attr-test*/ +define('can-view-live@4.2.8#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', { + beforeEach: function () { + this.fixture = document.getElementById('qunit-fixture'); + } + }); + QUnit.test('basics', function (assert) { + 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); + assert.equal(div.className, 'foo end'); + firstValue.set(true); + assert.equal(div.className, 'foo selected end'); + secondValue.set(true); + assert.equal(div.className, 'foo selected active end'); + firstValue.set(false); + assert.equal(div.className, 'foo active end'); + }); + QUnit.test('specialAttribute with new line', function (assert) { + var div = document.createElement('div'); + var style = new SimpleObservable('width: 50px;\nheight:50px;'); + live.attr(div, 'style', style); + assert.equal(div.style.height, '50px'); + assert.equal(div.style.width, '50px'); + }); + QUnit.test('can.live.attr works with non-string attributes (#1790)', function (assert) { + var el = document.createElement('div'), attrCompute = new Observation(function () { + return 2; + }); + domMutateNode.setAttribute.call(el, 'value', 1); + live.attr(el, 'value', attrCompute); + assert.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 (assert) { + var el = document.createElement('input'), attrObservable = new SimpleObservable('Hello'); + live.attr(el, 'value', attrObservable); + assert.equal(el.value, 'Hello', 'Hello'); + attrObservable.set('Hi'); + assert.equal(el.value, 'Hi', 'Hi'); + el.value = 'Hey'; + assert.equal(el.value, 'Hey', 'Hey'); + attrObservable.set('Aloha'); + assert.equal(el.value, 'Aloha', 'Aloha'); + }); +}); +/*can-view-live@4.2.8#test/attrs-test*/ +define('can-view-live@4.2.8#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', { + beforeEach: function () { + this.fixture = document.getElementById('qunit-fixture'); + } + }); + QUnit.test('basics', function (assert) { + 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); + assert.equal(div.className, 'foo'); + property.set(null); + assert.equal(div.className, ''); + queues.batch.start(); + property.set('foo'); + value.set('bar'); + queues.batch.stop(); + assert.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.8#test/test*/ +define('can-view-live@4.2.8#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.3#can-view-model_test*/ +define('can-view-model@4.0.3#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 (assert) { + var el = document.createElement('div'); + viewModel(el, 'foo', 'bar'); + assert.equal(viewModel(el, 'foo'), 'bar'); + assert.ok(viewModel(el) instanceof SimpleMap, 'is SimpleMap'); + }); + QUnit.test('a selector can be passed as the first argument (#6)', function (assert) { + var el = document.createElement('div'); + el.className = 'the-el'; + document.getElementById('qunit-fixture').appendChild(el); + viewModel('.the-el', 'foo', 'bar'); + assert.equal(viewModel('.the-el', 'foo'), 'bar'); + assert.ok(viewModel(el) instanceof SimpleMap, 'is can-map'); + }); + QUnit.test('set custom can-simple-map on element (#5)', function (assert) { + 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); + assert.equal(viewModel(el, 'foo'), 'bar'); + }); + QUnit.test('Allow passing array like (jQuery) element', function (assert) { + 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'); + assert.equal(viewModel('.the-el', 'foo'), 'bar', 'It reads view scope from html element'); + assert.equal(viewModel($el, 'foo'), 'bar', 'It reads view scope from array like (jQuery) element'); + assert.ok(viewModel(el) instanceof SimpleMap, 'is can-map'); + }); + QUnit.test('elements with length property not treated as arraylikes (#31)', function (assert) { + var el = document.createElement('select'); + document.getElementById('qunit-fixture').appendChild(el); + assert.equal(el.length, 0, 'Select has length property (0 for empty)'); + assert.deepEqual(viewModel(el).get(), {}, 'viewModel created on empty select'); + var opt = document.createElement('option'); + el.appendChild(opt); + assert.equal(el.length, 1, 'Select has length 1'); + assert.deepEqual(viewModel(el).get(), {}, 'viewModel created on non-empty select'); + }); +}); +/*can-view-model@4.0.3#test/test*/ +define('can-view-model@4.0.3#test/test', [ + 'require', + 'exports', + 'module', + '../can-view-model_test' +], function (require, exports, module) { + require('../can-view-model_test'); +}); +/*can-view-nodelist@4.3.4#test/can-view-nodelist-test*/ +define('can-view-nodelist@4.3.4#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'); + QUnit.test('unregisters child nodeLists', function (assert) { + assert.expect(4); + var spansFrag = fragment('12'); + var spansList = canReflect.toArray(spansFrag.childNodes); + nodeLists.register(spansList, function () { + assert.ok(true, 'unregistered spansList'); + }); + var labelFrag = fragment(''); + var labelList = canReflect.toArray(labelFrag.childNodes); + nodeLists.register(labelList, function () { + assert.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 () { + assert.ok(true, 'unregistered ifList'); + }); + assert.deepEqual(ifList, [ + ifEls[0], + spansList, + ifEls[2], + labelList + ]); + nodeLists.update(ifList, [document.createTextNode('empty')]); + assert.ok(labelList.isUnregistered, 'labelList was unregistered'); + }); + QUnit.test('.remove doesn\'t remove elements not in the parent', function (assert) { + var notIn = document.createTextNode('test'); + var parent = document.createElement('div'); + parent.appendChild(document.createElement('span')); + parent.appendChild(document.createElement('section')); + try { + nodeLists.remove([ + parent.firstChild, + notIn, + parent.firstChild.nextSibling + ]); + assert.equal(parent.firstChild, null, 'No children now'); + } catch (err) { + assert.ok(false, err); + } + }); +}); +/*can-view-parser@4.1.3#test/can-view-parser-test*/ +define('can-view-parser@4.1.3#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 (assert, tests) { + var count = 0; + var makeCheck = function (name) { + return function () { + if (count >= tests.length) { + assert.ok(false, 'called ' + name + ' with ' + JSON.stringify([].slice.call(arguments))); + } else { + var test = tests[count], args = test[1]; + assert.equal(name, test[0], 'test ' + count + ' ' + name + '('); + for (var i = 0; i < args.length; i++) { + assert.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') + }; + }; + QUnit.test('html to html', function (assert) { + 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(assert, tests)); + }); + QUnit.test('uppercase html to html', function (assert) { + 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(assert, tests)); + }); + QUnit.test('camelCase attributes stay untouched (svg) - #22', function (assert) { + var tests = [ + [ + 'start', + [ + 'svg', + false + ] + ], + [ + 'attrStart', + ['viewBox'] + ], + [ + 'attrValue', + ['0 0 15 22'] + ], + [ + 'attrEnd', + ['viewBox'] + ], + [ + 'end', + [ + 'svg', + false + ] + ], + [ + 'close', + ['svg'] + ], + [ + 'done', + [] + ] + ]; + parser('', makeChecks(assert, tests)); + }); + QUnit.test('camelCase tags stay untouched (svg)', function (assert) { + var tests = [ + [ + 'start', + [ + 'svg', + false + ] + ], + [ + 'end', + [ + 'svg', + false + ] + ], + [ + 'start', + [ + 'radialGradient', + false + ] + ], + [ + 'end', + [ + 'radialGradient', + false + ] + ], + [ + 'close', + ['radialGradient'] + ], + [ + 'close', + ['svg'] + ], + [ + 'done', + [] + ] + ]; + parser('', makeChecks(assert, tests)); + }); + QUnit.test('special in an attribute in an in-tag section', function (assert) { + parser('
      ', makeChecks(assert, [ + [ + 'start', + [ + 'div', + false + ] + ], + [ + 'special', + ['#truthy'] + ], + [ + 'attrStart', + ['foo'] + ], + [ + 'special', + ['baz'] + ], + [ + 'attrEnd', + ['foo'] + ], + [ + 'special', + ['/truthy'] + ], + [ + 'end', + [ + 'div', + false + ] + ], + [ + 'close', + ['div'] + ], + [ + 'done', + [] + ] + ])); + }); + QUnit.test('special with a custom attribute', function (assert) { + parser('
      ', makeChecks(assert, [ + [ + 'start', + [ + 'div', + false + ] + ], + [ + 'special', + ['#attribute'] + ], + [ + 'special', + ['name'] + ], + [ + 'attrStart', + [''] + ], + [ + 'special', + ['value'] + ], + [ + 'attrEnd', + [''] + ], + [ + 'special', + ['/attribute'] + ], + [ + 'end', + [ + 'div', + false + ] + ], + [ + 'close', + ['div'] + ], + [ + 'done', + [] + ] + ])); + }); + QUnit.test('single attribute value', function (assert) { + parser('', makeChecks(assert, [ + [ + 'start', + [ + 'input', + true + ] + ], + [ + 'attrStart', + ['DISABLED'] + ], + [ + 'attrEnd', + ['DISABLED'] + ], + [ + 'end', + [ + 'input', + true + ] + ], + [ + 'done', + [] + ] + ])); + }); + QUnit.test('trailing linebreaks in IE', function (assert) { + parser('12345{{!\n This is a\n multi-line comment...\n}}67890\n', makeChecks(assert, [ + [ + 'chars', + ['12345'] + ], + [ + 'special', + ['!\n This is a\n multi-line comment...\n'] + ], + [ + 'chars', + ['67890\n'] + ], + [ + 'done', + [] + ] + ])); + }); + QUnit.test('block are allowed inside anchor tags', function (assert) { + parser('
      ', makeChecks(assert, [ + [ + 'start', + [ + 'a', + false + ] + ], + [ + 'end', + [ + 'a', + false + ] + ], + [ + 'start', + [ + 'div', + false + ] + ], + [ + 'end', + [ + 'div', + false + ] + ], + [ + 'close', + ['div'] + ], + [ + 'close', + ['a'] + ], + [ + 'done', + [] + ] + ])); + }); + QUnit.test('anchors are allowed as children of inline elements - #2169', function (assert) { + parser('', makeChecks(assert, [ + [ + 'start', + [ + 'span', + false + ] + ], + [ + 'end', + [ + 'span', + false + ] + ], + [ + 'start', + [ + 'a', + false + ] + ], + [ + 'end', + [ + 'a', + false + ] + ], + [ + 'close', + ['a'] + ], + [ + 'close', + ['span'] + ], + [ + 'done', + [] + ] + ])); + }); + QUnit.test('inline tags encapsulate inner block elements', function (assert) { + parser('
      ', makeChecks(assert, [ + [ + 'start', + [ + 'span', + false + ] + ], + [ + 'end', + [ + 'span', + false + ] + ], + [ + 'start', + [ + 'div', + false + ] + ], + [ + 'end', + [ + 'div', + false + ] + ], + [ + 'close', + ['div'] + ], + [ + 'close', + ['span'] + ], + [ + 'done', + [] + ] + ])); + parser('

      ', makeChecks(assert, [ + [ + 'start', + [ + 'em', + false + ] + ], + [ + 'end', + [ + 'em', + false + ] + ], + [ + 'start', + [ + 'h1', + false + ] + ], + [ + 'end', + [ + 'h1', + false + ] + ], + [ + 'close', + ['h1'] + ], + [ + 'close', + ['em'] + ], + [ + 'done', + [] + ] + ])); + }); + QUnit.test('unordered lists will contain their list items', function (assert) { + parser('
      ', makeChecks(assert, [ + [ + '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', + [] + ] + ])); + }); + QUnit.test('supports single character attributes (#1132)', function (assert) { + parser('', makeChecks(assert, [ + [ + 'start', + [ + 'circle', + false + ] + ], + [ + 'attrStart', + ['r'] + ], + [ + 'attrValue', + ['25'] + ], + [ + 'attrEnd', + ['r'] + ], + [ + 'end', + [ + 'circle', + false + ] + ], + [ + 'close', + ['circle'] + ], + [ + 'done', + [] + ] + ])); + }); + QUnit.test('accept custom tag with colon ":" #1108', function (assert) { + parser('', makeChecks(assert, [ + [ + 'start', + [ + 'x:widget', + true + ] + ], + [ + 'end', + [ + 'x:widget', + true + ] + ], + [ + 'done', + [] + ] + ])); + }); + QUnit.test('output json', function (assert) { + 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(assert, tests), true); + parser(intermediate, makeChecks(assert, tests)); + }); + QUnit.test('less than outside of an element', function (assert) { + var tests = [ + [ + 'start', + [ + 'h1', + false + ] + ], + [ + 'end', + [ + 'h1', + false + ] + ], + [ + 'chars', + [' < '] + ], + [ + 'close', + ['h1'] + ], + [ + 'done', + [] + ] + ]; + var intermediate = parser('

      <

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

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

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

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

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

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

      bar

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

      bar

      ', makeChecks(assert, [ + [ + '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(assert, [ + [ + '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', + [] + ] + ])); + }); + QUnit.test('tags with data attributes are allowed in comments (#2)', function (assert) { + parser('{{! foo }}', makeChecks(assert, [ + [ + 'special', + ['! foo '] + ], + [ + 'done', + [] + ] + ])); + parser('{{! }}', makeChecks(assert, [ + [ + 'special', + ['! '] + ], + [ + 'done', + [] + ] + ])); + parser('{{! }}', makeChecks(assert, [ + [ + 'special', + ['! '] + ], + [ + 'done', + [] + ] + ])); + }); + QUnit.test('multiline special comments (#14)', function (assert) { + parser('{{! foo !}}', makeChecks(assert, [ + [ + 'special', + ['! foo !'] + ], + [ + 'done', + [] + ] + ])); + parser('{{! {{foo}} {{bar}} !}}', makeChecks(assert, [ + [ + 'special', + ['! {{foo}} {{bar}} !'] + ], + [ + 'done', + [] + ] + ])); + parser('{{!\n{{foo}}\n{{bar}}\n!}}', makeChecks(assert, [ + [ + 'special', + ['!\n{{foo}}\n{{bar}}\n!'] + ], + [ + 'done', + [] + ] + ])); + }); + QUnit.test('spaces in attribute names that start with `{` or `(` are encoded (#48)', function (assert) { + 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(assert, tests)); + }); + QUnit.test('for attributes without values, spaces in attribute names that start with `{` or `(` are encoded (#48)', function (assert) { + 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(assert, tests)); + }); + QUnit.test('mismatched brackets work: {(foo})', function (assert) { + var tests = [ + [ + 'start', + [ + 'h1', + false + ] + ], + [ + 'attrStart', + [encoder.encode('{(foo})')] + ], + [ + 'attrValue', + ['a'] + ], + [ + 'attrEnd', + [encoder.encode('{(foo})')] + ], + [ + 'end', + [ + 'h1', + false + ] + ], + [ + 'close', + ['h1'] + ], + [ + 'done', + [] + ] + ]; + parser('

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

      ', makeChecks(assert, tests)); + }); + QUnit.test('forward slashes are encoded (#52)', function (assert) { + 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(assert, tests)); + }); + QUnit.test('camelCase properties are encoded with on:, :to, :from, :bind bindings', function (assert) { + 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(assert, tests)); + }); + testHelpers.dev.devOnlyTest('Warn on missing attribute value end quotes (canjs/can-view-parser#7)', function (assert) { + var makeWarnChecks = function (input, texts) { + var count = 0; + var teardown = testHelpers.dev.willWarn(/End quote is missing for/, function (message, matched) { + assert.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 () { + } + }); + assert.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']); + }); + QUnit.test('TextNodes are not inserted before the or after the ', function (assert) { + 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(assert, tests)); + }); +}); +/*can-view-scope@4.13.6#test/variable-scope-test*/ +define('can-view-scope@4.13.6#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 (assert) { + var root = { + rootProp: 'ROOT', + conflictProp: 'ROOT' + }; + var scope = new Scope(root).add({ + variableProp: 'VARIABLE', + conflictProp: 'VARIABLE' + }, { variable: true }); + assert.equal(scope.get('variableProp'), 'VARIABLE', 'can read a variable'); + assert.equal(scope.get('this.rootProp'), 'ROOT', 'can pass variables for the root'); + assert.equal(scope.get('this.conflictProp'), 'ROOT', 'this.conflictProp'); + assert.equal(scope.get('./conflictProp'), 'ROOT', './conflictProp'); + assert.equal(scope.get('conflictProp'), 'VARIABLE', 'conflictProp'); + assert.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 }); + assert.equal(scope2.get('variableProp'), 'VARIABLE', 'can read a variable'); + assert.equal(scope2.get('this.root2Prop'), 'ROOT2', 'can pass variables for the root 2'); + assert.equal(scope2.get('this.conflictProp'), 'ROOT2', 'this.conflictProp'); + assert.equal(scope2.get('./conflictProp'), 'ROOT2', './conflictProp'); + assert.equal(scope2.get('conflictProp'), 'VARIABLE', 'conflictProp'); + assert.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 }); + assert.equal(scope3.get('../../conflictProp'), 'ROOT', '../../conflictProp'); + }); + QUnit.test('writing', function (assert) { + var root = new SimpleMap({ name: 'ROOT' }); + var scope; + scope = new Scope(root).addLetContext(); + scope.set('rootProp', 'VALUE'); + assert.equal(root.get('rootProp'), 'VALUE', 'wrote to property with .set'); + var rootProp = scope.computeData('rootProp2'); + canReflect.setValue(rootProp, 'VALUE2'); + assert.equal(root.get('rootProp2'), 'VALUE2', 'wrote property by setting ScopeKeyData'); + var rootProp3 = scope.computeData('rootProp3'); + canReflect.onValue(rootProp3, function () { + }); + canReflect.setValue(rootProp3, 'VALUE3'); + assert.equal(root.get('rootProp3'), 'VALUE3', 'wrote to property by setting bound ScopeKeyData'); + scope = new Scope(root).addLetContext({ tempProp: undefined }); + scope.set('tempProp', 'foo'); + assert.equal(root.get('tempProp'), undefined, 'write to undefined not set on root'); + assert.equal(scope.get('tempProp'), 'foo', 'able to read from root'); + }); +}); +/*can-view-scope@4.13.6#test/scope-set-test*/ +define('can-view-scope@4.13.6#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 (assert) { + var value = new SimpleObservable(1); + var scope = new Scope(value); + scope.set('this', 2); + assert.equal(scope.get('this'), 2, 'this read value'); + scope.set('.', 3); + assert.equal(scope.get('this'), 3, '. read value'); + scope = scope.add({}); + scope.set('..', 4); + assert.equal(scope.get('..'), 4, '.. read value'); + }); + QUnit.test('can set scope attributes with ../ (#2132)', function (assert) { + var map = new SimpleMap(); + var scope = new Scope(map); + var top = scope.add(new SimpleMap()); + top.set('../foo', 'bar'); + assert.equal(map.attr('foo'), 'bar'); + }); + QUnit.test('Scope attributes can be set (#1297, #1304)', function (assert) { + 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'); + assert.equal(scope.get('name'), 'Wilbur', 'set(key) updated'); + scope.set('other.person.name', 'Dave'); + assert.equal(scope.get('other.person.name'), 'Dave', 'set(key.key.key) updated'); + scope.set('other.comp', 'Changed'); + assert.equal(comp.get(), 'Changed', 'set(key.compute) updated'); + scope = new Scope(map); + scope.set('other.name', 'Brian'); + assert.equal(scope.get('other.name'), 'Brian', 'Value updated'); + assert.equal(map.attr('other').attr('name'), 'Brian', 'Name update in map'); + }); + QUnit.test('setting a key on a non observable context', function (assert) { + var context = { colors: new SimpleMap() }; + var scope = new Scope(context); + scope.set('colors', { prop: 'bar' }); + assert.deepEqual(context.colors.attr(), { prop: 'bar' }, 'can updateDeep'); + }); + QUnit.test('filename and lineNumber can be read from anywhere in scope chain', function (assert) { + var parent = new Scope({}); + var scope = parent.add({}); + parent.set('scope.filename', 'my-cool-file.txt'); + parent.set('scope.lineNumber', '5'); + assert.equal(scope.peek('scope.filename'), 'my-cool-file.txt', 'scope.peek("scope.filename")'); + assert.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 (assert) { + var teardown = testHelpers.dev.willError(/Attempting to set a value at (.+) where (.+) is undefined./); + var scope = new Scope({}); + scope.set('../person.name', 'Christopher'); + assert.equal(teardown(), 1, 'saw errors'); + }); +}); +/*can-view-scope@4.13.6#test/scope-key-data-test*/ +define('can-view-scope@4.13.6#test/scope-key-data-test', [ + 'require', + 'exports', + 'module', + 'can-view-scope', + 'can-simple-map', + 'steal-qunit', + 'can-symbol', + 'can-reflect', + 'can-simple-observable', + 'can-observation', + 'can-observation-recorder', + 'can-test-helpers' +], function (require, exports, module) { + var Scope = require('can-view-scope'); + var SimpleMap = require('can-simple-map'); + var QUnit = require('steal-qunit'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + var SimpleObservable = require('can-simple-observable'); + var Observation = require('can-observation'); + var ObservationRecorder = require('can-observation-recorder'); + var testHelpers = require('can-test-helpers'); + QUnit.module('can-view-scope scope-key-data'); + QUnit.test('able to scope-key-data this', function (assert) { + var value = new SimpleObservable(1); + var scope = new Scope(value); + var thisObservable = scope.computeData('this'); + thisObservable.on(function () { + }); + assert.equal(canReflect.getValue(thisObservable), 1); + canReflect.setValue(thisObservable, 2); + }); + QUnit.test('ScopeKeyData\'s thisArg is observable', function (assert) { + 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) { + assert.equal(value, 'B'); + }); + context.set('foo', { + doSomething: doSomething, + value: 'B' + }); + }); + QUnit.test('reading ScopeKeyData will update underlying observable', function (assert) { + var context = new SimpleMap({ 'prop': 'value' }); + var prop = new Scope(context).computeData('this.prop', { proxyMethods: false }); + canReflect.onValue(prop, function () { + }); + context.on('prop', function () { + assert.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 () { + assert.equal(canReflect.getValue(prop), 'VALUE', 'able to read deep, non-fast-path value'); + }, 'notify'); + root.value = 'VALUE'; + }); + QUnit.test('able to read from primitives (#197)', function (assert) { + var map = new SimpleMap({ someProperty: 'hello' }); + var scope = new Scope(map); + var scopeKeyData = scope.computeData('someProperty@split'); + canReflect.onValue(scopeKeyData, function () { + }); + assert.ok(true, 'does not error'); + }); + QUnit.test('initialValue should not emit ObservationRecords (#198)', function (assert) { + var map = new SimpleMap({ someProperty: 'hello' }); + var scope = new Scope(map); + var scopeKeyData = scope.computeData('someProperty'); + ObservationRecorder.start(); + assert.equal(scopeKeyData.initialValue, 'hello'); + var records = ObservationRecorder.stop(); + assert.equal(records.valueDependencies.size, 0, 'no value deps'); + }); + QUnit.test('Implements can.setElement', function (assert) { + var observation = new Observation(function () { + return 'test'; + }); + var map = new SimpleMap({ someProp: observation }); + var scope = new Scope(map); + var scopeKeyData = scope.computeData('someProp'); + scopeKeyData[canSymbol.for('can.setElement')](document.createElement('div')); + assert.ok(true, 'ScopeKeyData has can.setElement'); + }); + testHelpers.dev.devOnlyTest('Warn when key is not found and log the value of the last property that can be read #206', function (assert) { + var teardown = testHelpers.dev.willWarn(/Unable to find key "foo.length". Found "foo" with value: %o/, function (message, matched) { + assert.ok(matched, 'warning displayed'); + }); + var context = { foo: true }; + var scope = new Scope(context); + var scopeKeyData = scope.computeData('foo.length', { warnOnMissingKey: true }); + scopeKeyData.read(); + teardown(); + }); + testHelpers.dev.devOnlyTest('Warn when key is not defined #206', function (assert) { + var teardown = testHelpers.dev.willWarn('Unable to find key "foo.length".', function (message, matched) { + assert.ok(matched, 'warning is not displayed'); + }); + var scope = new Scope({}); + var scopeKeyData = scope.computeData('foo.length', { warnOnMissingKey: true }); + scopeKeyData.read(); + teardown(); + }); +}); +/*can-view-scope@4.13.6#test/scope-test*/ +define('can-view-scope@4.13.6#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'); + QUnit.test('basics', function (assert) { + 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 () { + }); + assert.deepEqual(nameInfo.reads, [{ + key: 'name', + at: false + }], 'reads'); + assert.equal(nameInfo.scope, personScope, 'scope'); + assert.equal(nameInfo.value, 'Justin', 'value'); + assert.equal(nameInfo.rootObserve, person, 'rootObserve'); + }); + QUnit.test('Scope.prototype.computeData', function (assert) { + var map = new SimpleMap(); + var base = new Scope(map); + var computeData = base.computeData('age'); + assert.equal(computeData.observation, computeData.options.observation, 'ScopeKeyData should have a backing observation stored on its `options`'); + var age = computeData.compute; + assert.equal(age(), undefined, 'age is not set'); + age.bind('change', function (ev, newVal, oldVal) { + assert.equal(newVal, 31, 'newVal is provided correctly'); + assert.equal(oldVal, undefined, 'oldVal is undefined'); + }); + age(31); + assert.equal(map.attr('age'), 31, 'maps age is set correctly'); + }); + QUnit.test('backtrack path (#163)', function (assert) { + var row = new SimpleMap({ first: 'Justin' }), col = { format: 'str' }, base = new Scope(row), cur = base.add(col); + assert.equal(cur.peek('.'), col, 'got col'); + assert.equal(cur.peek('..'), row, 'got row'); + assert.equal(cur.peek('../first'), 'Justin', 'got row'); + }); + QUnit.test('nested properties with compute', function (assert) { + 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) { + assert.equal(oldVal, 'Justin'); + assert.equal(newVal, 'Brian'); + } else if (changes === 1) { + assert.equal(oldVal, 'Brian'); + assert.equal(newVal, undefined); + } else if (changes === 2) { + assert.equal(oldVal, undefined); + assert.equal(newVal, 'Payal'); + } else if (changes === 3) { + assert.equal(oldVal, 'Payal'); + assert.equal(newVal, 'Curtis'); + } + changes++; + }; + compute.bind('change', handler); + assert.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); + }); + QUnit.test('function at the end', function (assert) { + var compute = new Scope({ + me: { + info: function () { + return 'Justin'; + } + } + }).computeData('me.info').compute; + assert.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; + assert.equal(compute2()(), 'Hank'); + }); + QUnit.test('binds to the right scope only', function (assert) { + 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) { + assert.equal(oldVal, 'Justin'); + assert.equal(newVal, 'Brian'); + }); + assert.equal(compute(), 'Justin'); + topMap.attr('me').attr('name').attr('first', 'Payal'); + baseMap.attr('me').attr('name').attr('first', 'Brian'); + }); + QUnit.test('Scope read returnObserveMethods=true', function (assert) { + var MapConstruct = SimpleMap.extend({ + foo: function (arg) { + assert.equal(this, data.map, 'correct this'); + assert.equal(arg, true, 'correct arg'); + } + }); + var data = { map: new MapConstruct() }; + var res = Scope.read(data, observeReader.reads('map.foo'), { isArgument: true }); + res.value(true); + }); + QUnit.test('rooted observable is able to update correctly', function (assert) { + var baseMap = new SimpleMap({ name: new SimpleMap({ first: 'Justin' }) }); + var scope = new Scope(baseMap); + var compute = scope.computeData('name.first').compute; + assert.equal(compute(), 'Justin'); + baseMap.attr('name', new SimpleMap({ first: 'Brian' })); + assert.equal(compute(), 'Brian'); + }); + QUnit.test('computeData reading an object with a compute', function (assert) { + var age = new SimpleObservable(21); + var scope = new Scope({ person: { age: age } }); + var computeData = scope.computeData('person.age'); + var value = computeData.compute(); + assert.equal(value, 21, 'correct value'); + computeData.compute(31); + assert.equal(age.get(), 31, 'age updated'); + }); + QUnit.test('computeData with initial empty compute (#638)', function (assert) { + assert.expect(2); + var c = new SimpleObservable(); + var scope = new Scope({ compute: c }); + var computeData = scope.computeData('compute'); + assert.equal(computeData.compute(), undefined); + computeData.compute.bind('change', function (ev, newVal) { + assert.equal(newVal, 'compute value'); + }); + c.set('compute value'); + }); + QUnit.test('Can read static properties on constructors (#634)', function (assert) { + var Foo = SimpleMap.extend({ static_prop: 'baz' }, { proto_prop: 'thud' }); + var data = new Foo({ own_prop: 'quux' }), scope = new Scope(data); + assert.equal(scope.computeData('constructor.static_prop').compute(), 'baz', 'static prop'); + }); + QUnit.test('Can read static properties on constructors (#634)', function (assert) { + var Foo = SimpleMap.extend({ static_prop: 'baz' }, { proto_prop: 'thud' }); + var data = new Foo({ own_prop: 'quux' }), scope = new Scope(data); + assert.equal(scope.computeData('constructor.static_prop').compute(), 'baz', 'static prop'); + }); + QUnit.test('Scope lookup restricted to current scope with ./ (#874)', function (assert) { + var current; + var scope = new Scope(new SimpleMap({ value: 'A Value' })).add(current = new SimpleMap({})); + var compute = scope.computeData('./value').compute; + assert.equal(compute(), undefined, 'no initial value'); + compute.bind('change', function (ev, newVal) { + assert.equal(newVal, 'B Value', 'changed'); + }); + compute('B Value'); + assert.equal(current.attr('value'), 'B Value', 'updated'); + }); + QUnit.test('reading properties on undefined (#1314)', function (assert) { + var scope = new Scope(undefined); + var compute = scope.compute('property'); + assert.equal(compute(), undefined, 'got back undefined'); + }); + QUnit.test('computeData.compute get/sets computes in maps', function (assert) { + var cmpt = new SimpleObservable(4); + var map = new SimpleMap(); + map.attr('computer', cmpt); + var scope = new Scope(map); + var computeData = scope.computeData('computer', {}); + assert.equal(computeData.compute(), 4, 'got the value'); + computeData.compute(5); + assert.equal(cmpt.get(), 5, 'updated compute value'); + assert.equal(computeData.compute(), 5, 'the compute has the right value'); + }); + QUnit.test('computesData can find update when initially undefined parent scope becomes defined (#579)', function (assert) { + assert.expect(2); + var map = new SimpleMap(); + var scope = new Scope(map); + var top = scope.add(new SimpleMap()); + var computeData = top.computeData('../value', {}); + assert.equal(computeData.compute(), undefined, 'initially undefined'); + computeData.compute.bind('change', function (ev, newVal) { + assert.equal(newVal, 'first'); + }); + map.attr('value', 'first'); + }); + QUnit.test('can read parent context with ../ (#2244)', function (assert) { + var map = new SimpleMap(); + var scope = new Scope(map); + var top = scope.add(new SimpleMap()); + assert.equal(top.peek('../'), map, 'looked up value correctly'); + }); + QUnit.test('trying to read constructor from refs scope is ok', function (assert) { + var map = new TemplateContext(); + var construct = new Observation(function () { + return map.constructor; + }); + canReflect.onValue(construct, function () { + }); + assert.equal(canReflect.getValue(construct), TemplateContext); + }); + QUnit.test('reading from a string in a nested scope doesn\'t throw an error (#22)', function (assert) { + var foo = new SimpleObservable('foo'); + var bar = new SimpleObservable('bar'); + var scope = new Scope(foo); + var localScope = scope.add(bar); + assert.equal(localScope.read('foo').value, undefined); + }); + QUnit.test('Optimize for compute().observableProperty (#29)', function (assert) { + 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) { + assert.equal(newVal, 'b'); + assert.equal(oldVal, 'a'); + assert.ok(scopeKeyData.fastPath, 'still fast path'); + changeNumber++; + wrap.set(new SimpleMap({ value: 'c' })); + } else if (changeNumber === 2) { + assert.equal(newVal, 'c', 'got new value'); + assert.equal(oldVal, 'b', 'got old value'); + assert.notOk(scopeKeyData.fastPath, 'still fast path'); + } + }); + assert.ok(scopeKeyData.fastPath, 'fast path'); + changeNumber++; + map.attr('value', 'b'); + }); + QUnit.test('a compute can observe the ScopeKeyData', function (assert) { + assert.expect(3); + 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 () { + assert.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) { + assert.equal(newValue, 'Ab', 'observation changed'); + }); + map.attr('value', 'A'); + }); + QUnit.test('unbinding clears all event bindings', function (assert) { + var ready = assert.async(); + 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) { + assert.equal(newValue, 'Ab'); + }; + canReflect.onValue(c, handlers); + canReflect.offValue(c, handlers); + setTimeout(function () { + var handlers = map[canSymbol.for('can.meta')].handlers.get([]); + assert.equal(handlers.length, 0, 'there are no bindings'); + ready(); + }, 30); + }); + QUnit.test('computes are read as this and . and ../', function (assert) { + var value = new SimpleObservable(1); + var scope = new Scope(value); + assert.equal(scope.get('this'), 1, 'this read value'); + assert.equal(scope.get('.'), 1, '. read value'); + scope = scope.add({}); + assert.equal(scope.get('..'), 1, '.. read value'); + }); + QUnit.test('maps are set with this.foo and ./foo', function (assert) { + var map = new SimpleObservable(new SimpleMap({ value: 1 })); + var scope = new Scope(map); + scope.set('this.value', 2); + assert.equal(scope.get('this.value'), 2, 'this read value'); + scope.set('./value', 3); + assert.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 (assert) { + 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); + assert.equal(scopeKeyData.observation.dependencyChange, Observation.prototype.dependencyChange, 'dependencyChange should be restored'); + assert.equal(scopeKeyData.observation.start, Observation.prototype.start, 'start should be restored'); + }); + QUnit.test('Rendering a template with a custom scope (#55)', function (assert) { + var scope = new Scope({}); + assert.equal(scope.get('name'), undefined, 'No name'); + scope.set('name', 'John'); + assert.equal(scope.get('name'), 'John', 'Got the name'); + scope = scope.add({ name: 'Justin' }); + assert.equal(scope.get('name'), 'Justin', 'Got the top scope name'); + }); + QUnit.test('./ scope lookup should read current scope', function (assert) { + var parent = new SimpleMap(); + var map = new SimpleMap(); + var scope = new Scope(parent).add(map); + assert.equal(scope.get('./'), map); + }); + QUnit.test('getTemplateContext() gives a scope with the templateContext', function (assert) { + var map = new SimpleMap(); + var scope = new Scope(map); + var templateContext = scope.getTemplateContext(); + assert.ok(templateContext instanceof Scope, 'templateContext is a Scope'); + assert.ok(templateContext._context instanceof TemplateContext, 'templateContext context is a TemplateContext object'); + }); + QUnit.test('scope can be used to read from the templateContext', function (assert) { + var map = new SimpleMap(); + var scope = new Scope(map); + assert.deepEqual(scope.peek('scope'), scope, 'scope'); + scope.set('scope.vars.name', 'Kevin'); + assert.equal(scope.peek('scope.vars.name'), 'Kevin', 'scope.vars.name === Kevin'); + var ageFn = function () { + return '30'; + }; + scope.set('scope.vars.age', ageFn); + assert.equal(scope.peek('scope.vars.age')(), '30', 'scope.vars.age === 30'); + }); + QUnit.test('scope.index reads from special scopes', function (assert) { + var originalIndexHelper = canStacheHelpers.index; + delete canStacheHelpers.index; + var map1 = new SimpleMap({ index: 1 }); + var map2 = new SimpleMap({ index: 3 }); + var scope = new Scope(map1); + assert.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 }); + assert.equal(scope.peek('scope.index'), 0, 'scope.index is read correctly'); + assert.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 (assert) { + var mockGlobalHelper = function () { + assert.ok(false, 'global helper should not be called'); + }; + var originalIndexHelper = canStacheHelpers.index; + canStacheHelpers.index = mockGlobalHelper; + var scope = new Scope({}); + assert.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 (assert) { + 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 }); + assert.equal(scope.peek('scope.key'), 'four', 'scope.key is read correctly'); + assert.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 (assert) { + var map = new SimpleMap({ scope1: 'this is scope1' }); + var scope = new Scope(map); + assert.deepEqual(scope.peek('scope1'), 'this is scope1', 'scope1'); + }); + QUnit.test('nested properties can be read from templateContext.vars', function (assert) { + var foo = new SimpleMap({ bar: 'baz' }); + var map = new SimpleMap(); + var scope = new Scope(map); + assert.ok(!scope.peek('scope.vars.foo.bar'), 'vars.foo.bar === undefined'); + scope.set('scope.vars.foo', foo); + assert.equal(scope.peek('scope.vars.foo.bar'), 'baz', 'vars.foo.bar === baz'); + scope.set('scope.vars.foo.bar', 'quz'); + assert.equal(scope.peek('scope.vars.foo.bar'), 'quz', 'vars.foo.bar === quz'); + }); + QUnit.test('nested properties can be read from scope.root', function (assert) { + var root = new SimpleMap({ bar: 'baz' }); + var map = new SimpleMap({ bar: 'abc' }); + var scope = new Scope(root).add(map); + assert.equal(scope.peek('scope.root.bar'), 'baz', 'root.bar === baz'); + }); + QUnit.test('special scopes are skipped if options.special !== true', function (assert) { + var map1 = new SimpleMap({}); + var scope = new Scope(map1).add({ foo: 'two' }, { special: true }).add({}); + assert.equal(scope.peek('foo', { special: true }), 'two', 'foo is read from special scope'); + }); + QUnit.test('special scopes are skipped when using ../.', function (assert) { + var obj = { foo: 'one' }; + var scope = new Scope(obj).add({ foo: 'two' }, { special: true }).add({}); + assert.equal(scope.peek('../.'), obj); + assert.equal(scope.peek('.././foo'), 'one'); + }); + QUnit.test('special scopes are skipped when using .', function (assert) { + var map = new SimpleMap({ foo: 'one' }); + var scope = new Scope(map).add({ foo: 'two' }, { special: true }); + assert.equal(scope.peek('.'), map); + }); + QUnit.test('this works everywhere (#45)', function (assert) { + var obj = { foo: 'bar' }; + var scope = new Scope(obj); + assert.equal(scope.get('this.foo'), 'bar'); + }); + QUnit.test('\'this\' and %context give the context', function (assert) { + assert.expect(1); + var vm; + var MyMap = SimpleMap.extend({ + doSomething: function () { + assert.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 (assert) { + 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); + assert.equal(instance.attr('prop'), 1); + }); + QUnit.test('undefined props should be a scope hit (#20)', function (assert) { + 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'); + assert.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'); + assert.equal(instance2.attr('value'), 'BAR'); + }); + QUnit.test('ScopeKeyData can.valueHasDependencies', function (assert) { + var map = new SimpleMap({ age: 21 }); + var base = new Scope(map); + var age = base.computeData('age'); + assert.equal(canReflect.valueHasDependencies(age), true, 'undefined'); + }); + QUnit.test('get and set Priority', function (assert) { + var map = new SimpleMap({ age: 21 }); + var base = new Scope(map); + var age = base.computeData('age'); + canReflect.setPriority(age, 5); + assert.equal(canReflect.getPriority(age), 5, 'set priority'); + var compute = age.compute; + assert.equal(canReflect.getPriority(compute), 5, 'set priority'); + }); + QUnit.test('fast path checking does not leak ObservationRecord.adds', function (assert) { + 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(); + assert.equal(dependencies.keyDependencies.size, 0, 'no key dependencies'); + assert.equal(dependencies.valueDependencies.size, 1, 'only sees age'); + assert.ok(dependencies.valueDependencies.has(age), 'only sees age'); + }); + QUnit.test('{{scope.set(...)}} works', function (assert) { + var map = new SimpleMap({ foo: 'bar' }); + var scope = new Scope(map); + var set = scope.peek('scope@set'); + set('foo', 'baz'); + assert.equal(map.get('foo'), 'baz', 'map.foo updated using scope.set'); + }); + QUnit.test('can read a method from scope.viewModel', function (assert) { + 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'); + assert.equal(method(), 'method return value'); + }); + QUnit.test('can read a value from scope.element', function (assert) { + var element = { value: 'element value' }; + var scope = new Scope({}).add({ element: element }, { special: true }); + var value = scope.peek('scope.element.value'); + assert.equal(value, 'element value'); + }); + QUnit.test('scope.find can be used to find a value in the first scope it exists', function (assert) { + 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); + assert.equal(scope.find('a'), 'a', 'a'); + assert.equal(scope.find('b'), 'b', 'b'); + assert.equal(scope.find('c'), 'c', 'c'); + }); + QUnit.test('scope.find accepts readOptions', function (assert) { + 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'); + assert.equal(aDotFunc(), a, 'a.func() got correct context'); + aDotFunc = scope.find('func', { proxyMethods: false }); + assert.notEqual(aDotFunc(), a, 'non-proxied a.func() got correct context'); + }); + QUnit.test('scope.read should not walk up normal scopes by default', function (assert) { + 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); + assert.equal(scope.read('a').value, 'a', 'a'); + assert.equal(scope.read('b').value, undefined, 'b'); + assert.equal(scope.read('c').value, undefined, 'c'); + }); + QUnit.test('scope.read should walk over special scopes', function (assert) { + var map = new SimpleMap({ + a: 'a', + b: 'b', + c: 'c' + }); + var scope = new Scope(map).add({ d: 'd' }, { special: true }); + assert.equal(scope.read('a').value, 'a', 'a'); + assert.equal(scope.read('b').value, 'b', 'b'); + assert.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 (assert) { + var scope = new Scope({ a: 'a' }).add({ b: 'b' }, { notContext: true }).add({ c: 'c' }, { special: true }).add({ d: 'd' }, { notContext: true }).add({ e: 'e' }); + assert.equal(scope.read('a').value, undefined, 'a not read from normal parent context'); + assert.equal(scope.read('b').value, 'b', 'b read correctly from notContext parent context'); + assert.equal(scope.read('c').value, undefined, 'c not read from special context'); + assert.equal(scope.read('d').value, 'd', 'd read correctly from notContext parent context'); + assert.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' }); + assert.equal(scope.read('e').value, undefined, 'e not read from normal parent context'); + assert.equal(scope.read('f').value, 'f', 'f read correctly from notContext parent context'); + assert.equal(scope.read('g').value, undefined, 'g not read from special context'); + assert.equal(scope.read('h').value, 'h', 'h read correctly from notContext parent context'); + assert.equal(scope.read('i').value, 'i', 'i read correctly'); + assert.equal(scope.read('../a').value, undefined, '../a not read from normal parent context above normal parent context'); + assert.equal(scope.read('../b').value, 'b', '../b read correctly from notContext parent context above normal parent context'); + assert.equal(scope.read('../c').value, undefined, '../c not read from special context above normal parent context'); + assert.equal(scope.read('../d').value, 'd', '../d read correctly from notContext parent context above normal parent context'); + assert.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 (assert) { + var scope = new Scope({}); + try { + assert.equal(scope.read('../foo').value, undefined, 'returns undefined'); + } catch (e) { + assert.ok(false, 'error occured: ' + e); + } + }); + QUnit.test('read checks templateContext helpers then global helpers after checking the scope', function (assert) { + 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; + assert.deepEqual(readScopeFunction(), 'scopeFunction', 'scopeFunction'); + var readLocalHelperFunction = scope.read('localHelperFunction').value; + assert.deepEqual(readLocalHelperFunction(), 'localHelperFunction', 'localHelperFunction'); + var readHelperFunction = scope.read('helperFunction').value; + assert.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 (assert) { + 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; + assert.deepEqual(readConsoleLog(), 'fakeConsole.log', 'fakeConsole.log'); + var readConsoleWarn = scope.read('console.warn').value; + assert.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 (assert) { + 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; + assert.deepEqual(localIf(), 'map.myIf', 'scope function'); + var globalIf = scope.read('scope.helpers.myIf').value; + assert.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 (assert) { + 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 }); + assert.equal(childName.value, child.name, 'childName.value === child.name'); + assert.equal(childName.thisArg, child, 'childName.thisArg === child'); + var childNameCompute = scope.computeData('child.name', { proxyMethods: false }); + Observation.temporarilyBind(childNameCompute); + assert.equal(childNameCompute.initialValue, child.name, 'childNameCompute.inititalValue === child.name'); + assert.equal(childNameCompute.thisArg, child, 'childNameCompute.thisArg === child'); + var rootFunc = scope.read('func', { proxyMethods: false }); + assert.equal(rootFunc.value, func, 'rootFunc.value === func'); + assert.equal(rootFunc.thisArg, childData, 'rootFunc.thisArg === childData'); + var myHelper = function () { + }; + canReflect.setKeyValue(scope.templateContext.helpers, 'myHelper', myHelper); + var helper = scope.read('myHelper', { proxyMethods: false }); + assert.equal(helper.value, myHelper, 'helper.value === func'); + assert.equal(helper.thisArg, undefined, 'helper.thisArg === undefined'); + var parentName = scope.read('../parent.name', { proxyMethods: false }); + assert.equal(parentName.value, parent.name, 'parentName.value === parent.name'); + assert.equal(parentName.thisArg, parent, 'parentName.thisArg === parent'); + var parentFunc = scope.read('../func', { proxyMethods: false }); + assert.equal(parentFunc.value, func, 'parentFunc.value === func'); + assert.equal(parentFunc.thisArg, parentData, 'rootFunc.thisArg === parentData'); + }); + QUnit.test('debugger is a reserved scope key for calling debugger helper', function (assert) { + var scope = new Scope({ name: 'Kevin' }); + var debuggerHelper = function (options) { + return options.scope.read('name').value; + }; + canStacheHelpers['debugger'] = debuggerHelper; + var debuggerScopeKey = scope.compute('debugger'); + assert.equal(canReflect.getValue(debuggerScopeKey), 'Kevin', 'debugger called with correct helper options'); + delete canStacheHelpers['debugger']; + }); + QUnit.test('scope.vm and scope.top', function (assert) { + var scope = new Scope({ name: 'foo' }).add({ name: 'Kevin' }, { viewModel: true }).add({ name: 'bar' }).add({ name: 'Ryan' }, { viewModel: true }).add({ name: 'baz' }); + assert.equal(scope.read('scope.vm.name').value, 'Ryan', 'scope.first can be used to read from the _first_ context with viewModel: true'); + assert.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 (assert) { + var teardown = testHelpers.dev.willWarn(/`scope.root` is deprecated/); + var scope = new Scope({ foo: 'bar' }); + scope.read('scope.root'); + assert.equal(teardown(), 1, 'deprecation warning displayed'); + }); + testHelpers.dev.devOnlyTest('scope.getPathsForKey', function (assert) { + 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'); + assert.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 (assert) { + 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'); + assert.deepEqual(paths, { + 'scope.vm.name()': vm, + 'scope.top.name()': top, + 'name()': nonVm, + '../../name()': vm, + '../../../name()': top + }); + }); + QUnit.test('scope.hasKey', function (assert) { + 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); + assert.equal(canReflect.hasKey(scope, 'scope.top.foo'), true, 'hasKey scope.top.foo === true'); + assert.equal(canReflect.hasKey(scope, 'scope.top.bar'), false, 'hasKey scope.top.bar === false'); + assert.equal(canReflect.hasKey(scope, 'scope.vm.bar'), true, 'hasKey scope.vm.bar === true'); + assert.equal(canReflect.hasKey(scope, 'scope.vm.baz'), false, 'hasKey scope.vm.baz === false'); + assert.equal(canReflect.hasKey(scope, 'baz'), true, 'hasKey baz === true'); + assert.equal(canReflect.hasKey(scope, 'foo'), false, 'hasKey foo === false'); + }); + QUnit.test('read returns correct `parentHasKey` value', function (assert) { + var vm = {}; + canReflect.assignSymbols(vm, { + 'can.hasKey': function (key) { + return key === 'foo'; + } + }); + var scope = new Scope(vm); + assert.ok(scope.read('foo').parentHasKey, 'parent has key \'foo\''); + assert.notOk(scope.read('bar').parentHasKey, 'parent does not have key \'bar\''); + }); + QUnit.test('computeData returns correct `parentHasKey` value', function (assert) { + 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(); + assert.ok(fooCompute.parentHasKey, 'parent has key \'foo\''); + assert.notOk(barCompute.parentHasKey, 'parent does not have key \'bar\''); + }); + QUnit.test('can get helpers from parent TemplateContext', function (assert) { + var scope = new Scope(new Scope.TemplateContext({ + helpers: { + foo: function () { + } + } + })).add(new Scope.TemplateContext()).add({}); + assert.ok(scope.get('foo'), 'got helper'); + }); + QUnit.test('do not error when reading a missing parent context (#183)', function (assert) { + var scope = new Scope(new Scope.TemplateContext({})).add({}, {}); + var results = scope.read('../key', {}); + assert.ok(results.noContextAvailable, 'no error'); + }); + QUnit.test('cloneFromRef clones meta', function (assert) { + var scope = new Scope({}).add(new Scope.TemplateContext({})).addLetContext({ tempProp: undefined }); + var copyScope = scope.cloneFromRef(); + assert.deepEqual(copyScope._meta, { variable: true }); + }); + QUnit.test('scope/key walks the scope', function (assert) { + var scope = new Scope({ + foo: 'bar', + baz: function () { + return 'quz'; + } + }).add({}).add({}); + var value = scope.peek('scope/foo'); + assert.equal(value, 'bar'); + value = scope.peek('@scope/baz'); + assert.equal(value(), 'quz'); + }); + QUnit.test('able to read partials', function (assert) { + var myPartial = function () { + }; + var scope = new Scope(new Scope.TemplateContext({ partials: { myPartial: myPartial } })).add({}); + var result = scope.get('myPartial'); + assert.equal(result, myPartial, 'read the value'); + }); + QUnit.test('properties can shadow functions on can-event-queue/map when there is a LetContext', function (assert) { + var scope = new Scope({ one: 'the one property' }).addLetContext(); + assert.equal(scope.get('one'), 'the one property', '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.6#test/test*/ +define('can-view-target@4.1.6#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'); + QUnit.test('basics', function (assert) { + var classCallback = function () { + assert.equal(this.nodeName.toLowerCase(), 'h1', 'class on the right element'); + this.className = 'selected'; + }, attributesCallback = function () { + assert.equal(this.nodeName.toLowerCase(), 'h1', 'attributes on the right element'); + }, textNodeCallback = function () { + assert.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, + '!' + ] + }] + }]); + assert.equal(data.clone.childNodes.length, 1, 'there is one child'); + var h1 = data.clone.childNodes[0]; + assert.equal(h1.nodeName.toLowerCase(), 'h1', 'there is one h1'); + assert.equal(h1.id, 'myh1', 'the h1 has the right id'); + assert.equal(h1.childNodes.length, 1, 'the h1 has span'); + assert.equal(h1.childNodes[0].childNodes.length, 3, 'the span has 3 children'); + assert.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]; + assert.equal(newH1.className, 'selected', 'got selected class name'); + assert.equal(newH1.innerHTML.toLowerCase(), 'hello world!'); + }); + QUnit.test('replacing items', function (assert) { + var data = target([ + function () { + this.parentNode.insertBefore(document.createTextNode('inserted'), this.nextSibling); + }, + 'hi', + function () { + assert.equal(this.previousSibling.nodeValue, 'hi', 'previous is as expected'); + } + ]); + data.hydrate(); + }); + QUnit.test('comments', function (assert) { + function foo(el) { + el.nodeValue = 'val'; + } + var data = target([ + { tag: 'h1' }, + { comment: 'foo bar' }, + { + comment: 'bax', + callbacks: [foo] + } + ]); + var node = data.clone.childNodes[1]; + assert.equal(node.nodeValue, 'foo bar', 'node value is right'); + assert.equal(node.nodeType, 8, 'node is a comment'); + assert.deepEqual(data.paths[0].path, [2], 'node path is right'); + assert.deepEqual(data.paths[0].callbacks, [{ callback: foo }], 'node callback is right'); + }); + QUnit.test('paths should be run in reverse order (#966)', function (assert) { + var data = target([{ + tag: 'h1', + attributes: [function () { + }], + children: [ + function () { + this.parentNode.insertBefore(document.createElement('div'), this.nextSibling); + }, + { + tag: 'span', + children: [function () { + assert.equal(this.nodeType, 3, 'got an element'); + }] + } + ] + }]); + data.hydrate(); + }); + QUnit.test('renderToVirtualDOM', function (assert) { + 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 }); + assert.equal(out.firstChild.nodeName, 'H1'); + assert.equal(out.firstChild.firstChild.nodeName, 'SPAN'); + assert.equal(out.firstChild.lastChild.nodeValue, 'foo'); + }); + QUnit.test('cloneNode works in IE11', function (assert) { + var frag = document.createDocumentFragment(); + var text = document.createTextNode('some-text'); + var MO = MUTATION_OBSERVER(); + var observer; + frag.appendChild(text); + var clone = target.cloneNode(frag); + assert.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); + assert.equal(clone.childNodes.length, 1, 'cloneNode should work after creating MutationObserver'); + } + }); + QUnit.test('cloneNode keeps non-default element namespace', function (assert) { + var frag = document.createDocumentFragment(); + var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); + frag.appendChild(svg); + var clone = target.cloneNode(frag); + assert.equal(clone.firstChild.namespaceURI, 'http://www.w3.org/2000/svg', 'cloneNode should keep non-default element namespace'); + }); + QUnit.test('SVG namespaceURI', function (assert) { + 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(); + assert.equal(frag.firstChild.getAttributeNode('xmlns').namespaceURI, 'http://www.w3.org/2000/xmlns/'); + }); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-stache-converters@4.2.6#can-stache-converters*/ +define('can-stache-converters@4.2.6#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.6#test/boolean-to-inList_test*/ +define('can-stache-converters@4.2.6#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', { + beforeEach: function (assert) { + this.fixture = document.getElementById('qunit-fixture'); + } + }); + QUnit.test('Works with checkboxes', function (assert) { + var template = stache(''); + var map = new DefineMap({ + item: 2, + list: new DefineList([ + 1, + 2, + 3 + ]) + }); + var frag = template(map); + var input = frag.firstChild; + assert.ok(input.checked, 'it is initially checked'); + assert.equal(map.list.indexOf(2), 1, 'two is in the list'); + input.checked = false; + domEvents.dispatch(input, 'change'); + assert.equal(map.list.indexOf(2), -1, 'No longer in the list'); + map.item = 3; + assert.ok(input.checked, '3 is in the list'); + map.item = 5; + assert.ok(!input.checked, '5 is not in the list'); + map.list.push(5); + assert.ok(input.checked, 'Now 5 is in the list'); + map.item = 6; + input.checked = true; + domEvents.dispatch(input, 'change'); + assert.equal(map.list.indexOf(6), 3, 'pushed into the list'); + }); + QUnit.test('If there is no list, treated as false', function (assert) { + var template = stache(''); + var map = new DefineMap({ + item: 2, + list: undefined + }); + var frag = template(map); + var input = frag.firstChild; + assert.ok(!input.checked, 'not checked because there is no list'); + input.checked = true; + domEvents.dispatch(input, 'change'); + assert.ok(true, 'no errors thrown'); + }); + QUnit.test('works with radio buttons', function (assert) { + 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); + assert.equal(radioOne.checked, false, 'Matthew not checked'); + assert.equal(radioTwo.checked, true, 'Wilbur is checked'); + radioOne.checked = true; + domEvents.dispatch(radioOne, 'change'); + assert.equal(radioOne.checked, true, 'Matthew is checked'); + assert.equal(radioTwo.checked, false, 'Wilbur is not checked'); + }); +}); +/*can-stache-converters@4.2.6#test/index-to-selected_test*/ +define('can-stache-converters@4.2.6#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 (assert) { + var template = stache(''); + var map = new DefineMap({ + person: 'Anne', + people: [ + 'Matthew', + 'Anne', + 'Wilbur' + ] + }); + var select = template(map).firstChild; + assert.equal(select.value, 1, 'initially set to the first value'); + select.value = 2; + domEvents.dispatch(select, 'change'); + assert.equal(map.person, 'Wilbur', 'now it is me'); + map.person = map.people.item(0); + assert.equal(select.value, 0, 'set back'); + select.value = 'none'; + domEvents.dispatch(select, 'change'); + assert.equal(map.person, undefined, 'now undefined because not in the list'); + }); + QUnit.test('chooses select option by the index from a list without ~', function (assert) { + var template = stache(''); + var map = new DefineMap({ + person: 'Anne', + people: [ + 'Matthew', + 'Anne', + 'Wilbur' + ] + }); + var select = template(map).firstChild; + assert.equal(select.value, 1, 'initially set to the first value'); + select.value = 2; + domEvents.dispatch(select, 'change'); + assert.equal(map.person, 'Wilbur', 'now it is me'); + map.person = map.people.item(0); + assert.equal(select.value, 0, 'set back'); + select.value = 'none'; + domEvents.dispatch(select, 'change'); + assert.equal(map.person, undefined, 'now undefined because not in the list'); + }); +}); +/*can-stache-converters@4.2.6#test/selected-to-index_test*/ +define('can-stache-converters@4.2.6#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 (assert) { + var template = stache(''); + var map = new DefineMap({ + index: '1', + people: [ + 'Matthew', + 'Anne', + 'Wilbur' + ] + }); + var input = template(map).firstChild; + assert.equal(input.value, 'Anne', 'initially set to the first value'); + input.value = 'Wilbur'; + domEvents.dispatch(input, 'change'); + assert.equal(map.index, '2', 'now it is me'); + map.index = '0'; + assert.equal(input.value, 'Matthew', 'set back'); + input.value = 'none'; + domEvents.dispatch(input, 'change'); + assert.equal(map.index, -1, 'now -1 because not in the list'); + }); + QUnit.test('sets index by the value from a list without ~', function (assert) { + var template = stache(''); + var map = new DefineMap({ + index: '1', + people: [ + 'Matthew', + 'Anne', + 'Wilbur' + ] + }); + var input = template(map).firstChild; + assert.equal(input.value, 'Anne', 'initially set to the first value'); + input.value = 'Wilbur'; + domEvents.dispatch(input, 'change'); + assert.equal(map.index, '2', 'now it is me'); + map.index = '0'; + assert.equal(input.value, 'Matthew', 'set back'); + input.value = 'none'; + domEvents.dispatch(input, 'change'); + assert.equal(map.index, -1, 'now -1 because not in the list'); + }); +}); +/*can-stache-converters@4.2.6#test/string-to-any_test*/ +define('can-stache-converters@4.2.6#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 (assert) { + 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'); + assert.ok(equality(map.val, expected), 'map\'s value updated to: ' + type); + map.val = 'test'; + map.val = expected; + assert.equal(select.value, type, 'select\'s value updated to: ' + type); + }); + }); + QUnit.test('Works on all the types without ~', function (assert) { + 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'); + assert.ok(equality(map.val, expected), 'map\'s value updated to: ' + type); + map.val = 'test'; + map.val = expected; + assert.equal(select.value, type, 'select\'s value updated to: ' + type); + }); + }); +}); +/*can-stache-converters@4.2.6#test/not_test*/ +define('can-stache-converters@4.2.6#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 (assert) { + var template = stache(''); + var map = new DefineMap({ val: true }); + var input = template(map).firstChild; + assert.equal(input.checked, false, 'initially false'); + map.val = false; + assert.equal(input.checked, true, 'true because map val is false'); + input.checked = false; + domEvents.dispatch(input, 'change'); + assert.equal(map.val, true, 'map is now true because checkbox is false'); + }); + QUnit.test('saves the inverse of the selected value', function (assert) { + var template = stache(''); + var map = new DefineMap({ val: true }); + var input = template(map).firstChild; + assert.equal(input.checked, false, 'initially false'); + map.val = false; + assert.equal(input.checked, true, 'true because map val is false'); + input.checked = false; + domEvents.dispatch(input, 'change'); + assert.equal(map.val, true, 'map is now true because checkbox is false'); + }); + QUnit.test('works with boolean-to-inList', function (assert) { + var template = stache(''); + var map = new DefineMap({ + item: 2, + list: new DefineList([ + 1, + 2, + 3 + ]) + }); + var input = template(map).firstChild; + assert.equal(input.checked, false, 'not checked because it is in the list'); + map.item = 4; + assert.equal(input.checked, true, 'checked because not in the list'); + input.checked = false; + domEvents.dispatch(input, 'change'); + assert.equal(map.list.indexOf(4), 3, 'it was pushed into the list'); + map.list.splice(3, 1); + assert.equal(input.checked, true, 'now it\'s checked because not in the list'); + }); +}); +/*can-compute@4.1.1#proto-compute*/ +define('can-compute@4.1.1#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.1#can-compute*/ +define('can-compute@4.1.1#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.6#test/either-or_test*/ +define('can-stache-converters@4.2.6#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 (assert) { + var renderer = stache(''); + var map = new DefineMap({ pref: 'Star Trek' }); + var input = renderer(map).firstChild; + assert.equal(input.checked, true, 'initial value is right'); + input.checked = false; + domEvents.dispatch(input, 'change'); + assert.equal(map.pref, 'Star Wars', 'changed because input changed'); + map.pref = 'Star Trek'; + assert.equal(input.checked, true, 'changed because map changed'); + }); + QUnit.test('initial null selection', function (assert) { + var renderer = stache(''); + var map = new DefineMap({ pref: null }); + var input = renderer(map).firstChild; + assert.equal(input.checked, false, 'checkbox is unchecked'); + assert.strictEqual(map.pref, 'No', 'null value changed to falsey case by checkbox'); + input.checked = true; + domEvents.dispatch(input, 'change'); + assert.equal(map.pref, 'Yes', 'map updated because check was checked'); + }); + QUnit.test('initial undefined selection', function (assert) { + var renderer = stache(''); + var map = new DefineMap({ pref: undefined }); + var input = renderer(map).firstChild; + assert.equal(input.checked, false, 'checkbox is unchecked'); + assert.strictEqual(map.pref, 'No', 'undefined value changed to falsey case by checkbox'); + input.checked = true; + domEvents.dispatch(input, 'change'); + assert.equal(map.pref, 'Yes', 'map updated because check was checked'); + }); + QUnit.test('initial no match selection', function (assert) { + var renderer = stache(''); + var map = new DefineMap({ pref: 'fubar' }); + var input = renderer(map).firstChild; + assert.equal(input.checked, false, 'checkbox is unchecked'); + assert.strictEqual(map.pref, 'No', 'fubar value changed to falsey case by checkbox'); + input.checked = true; + domEvents.dispatch(input, 'change'); + assert.equal(map.pref, 'Yes', 'map updated because check was checked'); + }); + QUnit.test('supports computes', function (assert) { + var renderer = stache(''); + var map = new DefineMap({ + pref: compute('Maybe'), + a: compute('Yes'), + b: compute('No') + }); + var input = renderer(map).firstChild; + assert.equal(input.checked, false, 'checkbox is unchecked'); + assert.strictEqual(map.pref(), 'No', 'chosen value changed to falsey case by checkbox'); + input.checked = true; + domEvents.dispatch(input, 'change'); + assert.equal(map.pref(), 'Yes', 'map updated because check was checked'); + input.checked = false; + domEvents.dispatch(input, 'change'); + assert.equal(map.pref(), 'No', 'map updated because check was unchecked'); + }); + QUnit.test('supports computes without ~', function (assert) { + var renderer = stache(''); + var map = new DefineMap({ + pref: compute('Maybe'), + a: compute('Yes'), + b: compute('No') + }); + var input = renderer(map).firstChild; + assert.equal(input.checked, false, 'checkbox is unchecked'); + assert.strictEqual(map.pref(), 'No', 'chosen value changed to falsey case by checkbox'); + input.checked = true; + domEvents.dispatch(input, 'change'); + assert.equal(map.pref(), 'Yes', 'map updated because check was checked'); + input.checked = false; + domEvents.dispatch(input, 'change'); + assert.equal(map.pref(), 'No', 'map updated because check was unchecked'); + }); +}); +/*can-stache-converters@4.2.6#test/equal_test*/ +define('can-stache-converters@4.2.6#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 (assert) { + var template = stache(''); + var attending = compute('yes'); + var yes = template({ attending: attending }).firstChild, no = yes.nextSibling; + assert.equal(yes.checked, true, 'initially a yes'); + assert.equal(no.checked, false, 'initially unchecked'); + attending('no'); + assert.equal(yes.checked, false, 'now not checked'); + assert.equal(no.checked, true, 'now checked'); + yes.checked = true; + domEvents.dispatch(yes, 'change'); + assert.equal(attending(), 'yes', 'now it is yes'); + assert.equal(yes.checked, true, 'yes is checked'); + assert.equal(no.checked, false, 'no is unchecked'); + }); + QUnit.test('works without ~', function (assert) { + var template = stache(''); + var attending = compute('yes'); + var yes = template({ attending: attending }).firstChild, no = yes.nextSibling; + assert.equal(yes.checked, true, 'initially a yes'); + assert.equal(no.checked, false, 'initially unchecked'); + attending('no'); + assert.equal(yes.checked, false, 'now not checked'); + assert.equal(no.checked, true, 'now checked'); + yes.checked = true; + domEvents.dispatch(yes, 'change'); + assert.equal(attending(), 'yes', 'now it is yes'); + assert.equal(yes.checked, true, 'yes is checked'); + assert.equal(no.checked, false, 'no is unchecked'); + }); + QUnit.test('Allows one-way binding when passed a non-compute as the first argument', function (assert) { + var template = stache(''); + var attending = compute(false); + var input = template({ attending: attending }).firstChild; + assert.equal(input.checked, false, 'initially false'); + attending(true); + assert.equal(input.checked, true, 'can be changed to true'); + input.checked = false; + assert.equal(attending(), true, 'does not change compute'); + }); + QUnit.test('Allow multiple expressions to be passed in', function (assert) { + var template = stache(''); + var foo = compute(true); + var bar = compute(false); + var input = template({ + foo: foo, + bar: bar + }).firstChild; + assert.equal(input.checked, false, 'initially unchecked'); + bar(true); + assert.equal(input.checked, true, 'now checked'); + foo(false); + bar(false); + assert.equal(input.checked, false, 'now unchecked'); + input.checked = true; + domEvents.dispatch(input, 'change'); + assert.equal(foo(), true, 'computed foo value is true'); + assert.equal(bar(), true, 'computed bar value is true'); + }); + QUnit.test('Allow multiple expressions to be passed in without ~', function (assert) { + var template = stache(''); + var foo = compute(true); + var bar = compute(false); + var input = template({ + foo: foo, + bar: bar + }).firstChild; + assert.equal(input.checked, false, 'initially unchecked'); + bar(true); + assert.equal(input.checked, true, 'now checked'); + foo(false); + bar(false); + assert.equal(input.checked, false, 'now unchecked'); + input.checked = true; + domEvents.dispatch(input, 'change'); + assert.equal(foo(), true, 'computed foo value is true'); + assert.equal(bar(), true, 'computed bar value is true'); + }); + QUnit.test('Allow non static values', function (assert) { + 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'); + assert.equal(input.checked, false, 'initially unchecked'); + bar.value = 'foobar'; + assert.equal(input.checked, true, 'now checked'); + }); +}); +/*can-stache-converters@4.2.6#test/test*/ +define('can-stache-converters@4.2.6#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.1#proto-compute_test*/ +define('can-compute@4.1.1#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'); + QUnit.test('single value compute', function (assert) { + assert.expect(2); + var num = new Compute(1); + num.bind('change', function (ev, newVal, oldVal) { + assert.equal(newVal, 2, 'newVal'); + assert.equal(oldVal, 1, 'oldVal'); + }); + num.set(2); + }); + QUnit.test('inner computes values are not bound to', function (assert) { + 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); + var done = assert.async(); + setTimeout(function () { + var handlers = num[canSymbol.for('can.meta')].handlers; + assert.equal(handlers.get([]).length, 1, 'compute only bound to once'); + done(); + }, 50); + }); + QUnit.test('compute.truthy', function (assert) { + 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) { + assert.equal(newVal, 2, '2 is the new val'); + } else if (num.get() === -1) { + assert.equal(newVal, 3, '3 is the new val'); + } else { + assert.ok(false, 'change should not be called'); + } + }); + assert.equal(tester.get(), 1, 'on bind, we call tester once'); + num.set(2); + num.set(1); + num.set(0); + num.set(-1); + }); + QUnit.test('a binding compute does not double read', function (assert) { + var sourceAge = 30, timesComputeIsCalled = 0; + var age = new Compute(function (newVal) { + timesComputeIsCalled++; + if (timesComputeIsCalled === 1) { + assert.ok(true, 'reading age to get value'); + } else if (timesComputeIsCalled === 2) { + assert.equal(newVal, 31, 'the second time should be an update'); + } else if (timesComputeIsCalled === 3) { + assert.ok(true, 'called after set to get the value'); + } else { + assert.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); + assert.equal(info.get(), 'I am 30'); + age.set(31); + assert.equal(info.get(), 'I am 31'); + }); + QUnit.test('cloning a setter compute (#547)', function (assert) { + var name = new Compute('', function (newVal) { + return this.txt + newVal; + }); + var cloned = name.clone({ txt: '.' }); + cloned.set('-'); + assert.equal(cloned.get(), '.-'); + }); + QUnit.test('compute updated method uses get and old value (#732)', function (assert) { + assert.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; + } + }); + assert.equal(value.get(), 1, 'original value'); + assert.ok(!input.onchange, 'nothing bound'); + value.set(2); + assert.equal(value.get(), 2, 'updated value'); + assert.equal(input.value, 2, 'updated input.value'); + value.bind('change', function (ev, newVal, oldVal) { + assert.equal(newVal, 3, 'newVal'); + assert.equal(oldVal, 2, 'oldVal'); + value.unbind('change', this.Constructor); + }); + assert.ok(input.onchange, 'binding to onchange'); + input.value = 3; + input.onchange({}); + assert.ok(!input.onchange, 'removed binding'); + assert.equal(value.get(), 3); + }); + QUnit.test('a compute updated by source changes within a batch is part of that batch', function (assert) { + 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) { + assert.ok(true, 'called change once'); + } else { + assert.ok(false, 'called change multiple times'); + } + callbacks++; + }); + queues.batch.start(); + computeA.set('A'); + computeB.set('B'); + queues.batch.stop(); + }); + QUnit.test('Compute.async can be like a normal getter', function (assert) { + var first = new Compute('Justin'), last = new Compute('Meyer'), fullName = Compute.async('', function () { + return first.get() + ' ' + last.get(); + }); + assert.equal(fullName.get(), 'Justin Meyer'); + }); + QUnit.test('Compute.async operate on single value', function (assert) { + 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 () { + }); + assert.deepEqual(obj.get(), { + a: 1, + b: 2 + }, 'object has all properties'); + a.set(0); + assert.deepEqual(obj.get(), { b: 2 }, 'removed a'); + b.set(0); + assert.deepEqual(obj.get(), {}, 'removed b'); + }); + QUnit.test('Compute.async async changing value', function (assert) { + 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 done = assert.async(); + 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 () { + done(); + } + } + ], changeNum = 0; + async.bind('change', function (ev, newVal, oldVal) { + var data = changeArgs[changeNum++]; + assert.equal(newVal, data.newVal, 'newVal is correct'); + assert.equal(oldVal, data.oldVal, 'oldVal is correct'); + setTimeout(data.run, 10); + }); + }); + QUnit.test('Compute.async read without binding', function (assert) { + var source = new Compute(1); + var async = Compute.async([], function (curVal, setVal) { + curVal.push(source.get()); + return curVal; + }); + assert.ok(async.get(), 'calling async worked'); + }); + QUnit.test('Compute.async set uses last set or initial value', function (assert) { + var add = new Compute(1); + var fnCount = 0; + var async = Compute.async(10, function (curVal) { + switch (fnCount++) { + case 0: + assert.equal(curVal, 10); + break; + case 1: + assert.equal(curVal, 20); + break; + case 2: + assert.equal(curVal, 30, 'on bind'); + break; + case 3: + assert.equal(curVal, 30, 'on bind'); + break; + } + return curVal + add.get(); + }); + assert.equal(async.get(), 11, 'initial value'); + async.set(20); + async.bind('change', function () { + }); + async.set(20); + async.set(30); + }); + QUnit.test('Change propagation in a batch with late bindings (#2412)', function (assert) { + 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) { + assert.equal(newVal, 'grandChild->childAA'); + }); + queues.batch.start(); + rootA.set('A'); + rootB.set('B'); + queues.batch.stop(); + }); + if (Compute.prototype.trace) { + QUnit.test('trace', function (assert) { + 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) { + assert.equal(newVal, 'grandChild->childAA'); + }); + var out = grandChild.trace(); + assert.equal(out.definition, fn, 'got the right function'); + assert.equal(out.computeValue, 'grandChild->b'); + grandChild.log(); + queues.batch.start(); + rootA.set('A'); + rootB.set('B'); + queues.batch.stop(); + grandChild.log(); + }); + } + QUnit.test('works with can-reflect', function (assert) { + assert.expect(5); + var c = new Compute(0); + assert.equal(canReflect.getValue(c), 0, 'unbound value'); + assert.ok(canReflect.isValueLike(c), 'isValueLike is true'); + assert.ok(!canReflect.valueHasDependencies(c), 'valueHasDependencies -- false'); + var d = new Compute(function () { + return c.get(); + }); + d.on('change', function () { + }); + assert.ok(canReflect.valueHasDependencies(d), 'valueHasDependencies -- true'); + c.set(1); + assert.equal(canReflect.getValue(d), 1, 'bound value'); + c.set(2); + }); + QUnit.test('can-reflect setValue', function (assert) { + var a = new Compute('a'); + canReflect.setValue(a, 'A'); + assert.equal(a.get(), 'A', 'compute'); + }); + QUnit.test('registered symbols', function (assert) { + var a = new Compute('a'); + assert.ok(a[canSymbol.for('can.isValueLike')], 'can.isValueLike'); + assert.equal(a[canSymbol.for('can.getValue')](), 'a', 'can.getValue'); + a[canSymbol.for('can.setValue')]('b'); + assert.equal(a.get(), 'b', 'can.setValue'); + function handler(val) { + assert.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.1#can-compute_test*/ +define('can-compute@4.1.1#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'); + QUnit.test('single value compute', function (assert) { + var num = compute(1); + num.on('change', function (ev, newVal, oldVal) { + assert.equal(newVal, 2, 'newVal'); + assert.equal(oldVal, 1, 'oldVal'); + }); + num(2); + }); + QUnit.test('inner computes values are not bound to', function (assert) { + 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); + var done = assert.async(); + setTimeout(function () { + assert.equal(num.computeInstance[metaSymbol].handlers.get([]).length, 1, 'inner compute only bound once'); + assert.equal(outer.computeInstance[metaSymbol].handlers.get([]).length, 1, 'outer compute only bound once'); + done(); + }, 50); + }); + QUnit.test('compute.truthy', function (assert) { + 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) { + assert.equal(newVal, 2, '2 is the new val'); + } else if (num() === -1) { + assert.equal(newVal, 3, '3 is the new val'); + } else { + assert.ok(false, 'change should not be called'); + } + }); + assert.equal(tester(), 1, 'on bind, we call tester once'); + num(numValue = 2); + num(numValue = 1); + num(numValue = 0); + num(numValue = -1); + }); + QUnit.test('a binding compute does not double read', function (assert) { + var sourceAge = 30, timesComputeIsCalled = 0; + var age = compute(function (newVal) { + timesComputeIsCalled++; + if (timesComputeIsCalled === 1) { + assert.ok(true, 'reading age to get value'); + } else if (timesComputeIsCalled === 2) { + assert.equal(newVal, 31, 'the second time should be an update'); + } else if (timesComputeIsCalled === 3) { + assert.ok(true, 'called after set to get the value'); + } else { + assert.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); + assert.equal(info(), 'I am 30'); + age(31); + assert.equal(info(), 'I am 31'); + }); + QUnit.test('cloning a setter compute (#547)', function (assert) { + var name = compute('', function (newVal) { + return this.txt + newVal; + }); + var cloned = name.clone({ txt: '.' }); + cloned('-'); + assert.equal(cloned(), '.-'); + }); + QUnit.test('compute updated method uses get and old value (#732)', function (assert) { + assert.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; + } + }); + assert.equal(value(), 1, 'original value'); + assert.ok(!input.onchange, 'nothing bound'); + value(2); + assert.equal(value(), 2, 'updated value'); + assert.equal(input.value, 2, 'updated input.value'); + function handler(ev, newVal, oldVal) { + assert.equal(newVal, 3, 'newVal'); + assert.equal(oldVal, 2, 'oldVal'); + value.unbind('change', handler); + } + value.bind('change', handler); + assert.ok(input.onchange, 'binding to onchange'); + input.value = 3; + input.onchange({}); + assert.ok(!input.onchange, 'removed binding'); + assert.equal(value(), 3); + }); + QUnit.test('a compute updated by source changes within a batch is part of that batch', function (assert) { + 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) { + assert.ok(true, 'called change once'); + } else { + assert.ok(false, 'called change multiple times'); + } + callbacks++; + }); + queues.batch.start(); + computeA('A'); + computeB('B'); + queues.batch.stop(); + }); + QUnit.test('compute.async can be like a normal getter', function (assert) { + var first = compute('Justin'), last = compute('Meyer'), fullName = compute.async('', function () { + return first() + ' ' + last(); + }); + assert.equal(fullName(), 'Justin Meyer'); + }); + QUnit.test('compute.async operate on single value', function (assert) { + 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 () { + }); + assert.deepEqual(obj(), { + a: 1, + b: 2 + }, 'object has all properties'); + a(0); + assert.deepEqual(obj(), { b: 2 }, 'removed a'); + b(0); + assert.deepEqual(obj(), {}, 'removed b'); + }); + QUnit.test('compute.async async changing value', function (assert) { + var a = compute(1); + var b = compute(2); + var done; + 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 () { + done(); + } + } + ], changeNum = 0; + done = assert.async(); + async.bind('change', function (ev, newVal, oldVal) { + var data = changeArgs[changeNum++]; + assert.equal(newVal, data.newVal, 'newVal is correct'); + assert.equal(oldVal, data.oldVal, 'oldVal is correct'); + setTimeout(data.run, 10); + }); + }); + QUnit.test('compute.async read without binding', function (assert) { + var source = compute(1); + var async = compute.async([], function (curVal, setVal) { + curVal.push(source()); + return curVal; + }); + assert.ok(async(), 'calling async worked'); + }); + QUnit.test('bug with nested computes and batch ordering (#1519)', function (assert) { + 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; + }); + assert.equal(combined(), true); + combined.bind('change', function () { + }); + queues.batch.start(); + root('b'); + queues.batch.stop(); + assert.equal(combined(), true); + }); + QUnit.test('compute change handler context is set to the function not compute', function (assert) { + var comp = compute(null); + comp.bind('change', function () { + assert.equal(typeof this, 'function'); + }); + comp('test'); + }); + QUnit.test('Calling .unbind() on un-bound compute does not throw an error', function (assert) { + var count = compute(0); + count.unbind('change'); + assert.ok(true, 'No error was thrown'); + }); + QUnit.test('dependent computes update in the right order (2093)', function (assert) { + var root = compute('a'), childB = compute(function () { + return root(); + }), combine = compute(function () { + return root() + childB(); + }); + combine.bind('change', function (ev, newVal) { + assert.equal(newVal, 'bb', 'concat changed'); + }); + root('b'); + }); + QUnit.test('dependent computes update in the right order with a batch (#2093)', function (assert) { + 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) { + assert.equal(newVal, 'bb', 'concat changed'); + }); + queues.batch.start(); + root('b'); + queues.batch.stop(); + }); + QUnit.test('bug with nested computes and batch ordering (#1519)', function (assert) { + 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; + }); + assert.equal(combined(), true); + combined.bind('change', function () { + }); + queues.batch.start(); + root('b'); + queues.batch.stop(); + assert.equal(combined(), true); + }); + QUnit.test('binding, unbinding, and rebinding works after a timeout (#2095)', function (assert) { + var root = compute(1), derived = compute(function () { + return root(); + }); + var change = function () { + }; + derived.bind('change', change); + derived.unbind('change', change); + var done = assert.async(); + setTimeout(function () { + derived.bind('change', function (ev, newVal, oldVal) { + assert.equal(newVal, 2, 'updated'); + done(); + }); + root(2); + }, 10); + }); + QUnit.test('ObservationRecorder.isRecording observes doesn\'t understand ObservationRecorder.ignore (#2099)', function (assert) { + assert.expect(0); + var c = compute(1); + c.computeInstance.bind = function () { + assert.ok(false); + }; + var outer = compute(function () { + ObservationRecorder.ignore(function () { + c(); + })(); + }); + outer.bind('change', function () { + }); + }); + QUnit.test('handles missing update order items (#2121)', function (assert) { + 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) { + assert.equal(newVal, 'ROOT1root2'); + }); + queues.batch.start(); + root1('ROOT1'); + queues.batch.stop(); + }); + QUnit.test('compute should not fire event when NaN is set multiple times #2128', function (assert) { + var c = compute(NaN); + compute.bind('change', function () { + assert.ok(false, 'change event should not be fired'); + }); + assert.ok(isNaN(c())); + c(NaN); + }); + QUnit.test('eventQueue.afterPreviousEvents firing too late (#2198)', function (assert) { + 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 () { + assert.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(); + }); + QUnit.test('Async getter causes infinite loop (#28)', function (assert) { + var changeCount = 0; + var idCompute = compute(1); + var done = assert.async(); + 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) { + assert.equal(changeCount, 4); + done(); + } else { + setTimeout(checkChangeCount, 10); + } + }; + checkChangeCount(); + }); + QUnit.test('Listening to input change', function (assert) { + var input = document.createElement('input'); + var comp = compute(input, 'value', 'input'); + comp.on('change', function () { + assert.ok(true, 'it changed'); + }); + input.value = 'foo'; + domDispatch(input, 'input'); + }); + QUnit.test('Setting an input to change', function (assert) { + var input = document.createElement('input'); + var comp = compute(input, 'value', 'input'); + comp('foo'); + assert.ok(input.value === 'foo'); + }); + QUnit.test('compute.truthy with functions (canjs/can-stache#172)', function (assert) { + var func = compute(function () { + return function () { + assert.ok(false, 'should not be run'); + }; + }); + var truthy = compute.truthy(func); + assert.equal(truthy(), true); + }); + QUnit.test('works with can-reflect', function (assert) { + assert.expect(5); + var c = compute(0); + assert.equal(canReflect.getValue(c), 0, 'unbound value'); + var handler = function (newValue) { + assert.equal(newValue, 1, 'observed new value'); + canReflect.offValue(c, handler); + }; + assert.ok(canReflect.isValueLike(c), 'isValueLike is true'); + canReflect.onValue(c, handler); + assert.equal(canReflect.valueHasDependencies(c), undefined, 'valueHasDependencies'); + c(1); + assert.equal(canReflect.getValue(c), 1, 'bound value'); + c(2); + }); + QUnit.test('can-reflect valueHasDependencies', function (assert) { + var a = compute('a'); + var b = compute('b'); + var c = compute(function () { + return a() + b(); + }); + c.on('change', function () { + }); + assert.ok(canReflect.valueHasDependencies(c), 'valueHasDependencies'); + }); + QUnit.test('registered symbols', function (assert) { + var a = compute('a'); + assert.ok(a[canSymbol.for('can.isValueLike')], 'can.isValueLike'); + assert.equal(a[canSymbol.for('can.getValue')](), 'a', 'can.getValue'); + a[canSymbol.for('can.setValue')]('b'); + assert.equal(a(), 'b', 'can.setValue'); + function handler(val) { + assert.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 (assert) { + var a = compute('a'); + canReflect.setValue(a, 'A'); + assert.equal(a(), 'A', 'compute'); + }); + QUnit.test('Calling .unbind() with no arguments should tear down all event handlers', function (assert) { + var count = compute(0); + count.on('change', function () { + console.log('Count changed'); + }); + var handlers = count.computeInstance[canSymbol.for('can.meta')].handlers; + assert.equal(handlers.get(['change']).length, 1, 'Change event added'); + count.unbind(); + assert.equal(handlers.get(['change']).length, 0, 'All events for compute removed'); + }); + QUnit.test('.off() unbinds a given handler', function (assert) { + var handler = function () { + }; + var c = compute('foo'); + c.on('change', handler); + var handlers = c.computeInstance[canSymbol.for('can.meta')].handlers; + assert.equal(handlers.get(['change']).length, 1, 'handler added'); + c.off('change', handler); + assert.equal(handlers.get(['change']).length, 0, 'hander removed'); + }); +}); +/*can-map@4.3.9#bubble*/ +define('can-map@4.3.9#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.9#map-helpers*/ +define('can-map@4.3.9#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.1#helpers*/ +define('can-cid@1.3.1#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.1#set/set*/ +define('can-cid@1.3.1#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.1#map/map*/ +define('can-cid@1.3.1#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.9#can-map*/ +define('can-map@4.3.9#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-observation', + '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 Observation = require('can-observation'); + 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 inSetupSymbol = canSymbol.for('can.initializing'); + 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[inSetupSymbol] ? undefined : this.___get(first); + if (canReflect.isMapLike(current)) { + canReflect.setKeyValue(current, second, value); + } else { + current = this[inSetupSymbol] ? undefined : this.___get(attr); + if (this.__convert) { + value = this.__convert(attr, value); + } + this.__set(attr, this.__type(value, attr), current); + } + } else { + current = this[inSetupSymbol] ? 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 (canReflect.isObservableLike(curVal) && canReflect.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, 'notify'); + } 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[inSetupSymbol]) { + 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.2#can-list*/ +define('can-list@4.2.2#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]); + canEvent.dispatch.call(this, 'can.patches', [patches]); + } 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]); + canEvent.dispatch.call(this, 'can.patches', [patches]); + } else { + canEvent.dispatch.call(this, how, [ + newVal, + index + ]); + } + } else { + Map.prototype._triggerChange.apply(this, arguments); + } + queues.batch.stop(); + }, + __get: function (prop) { + prop = isNaN(+prop) || prop % 1 ? prop : +prop; + if (typeof prop === 'number') { + ObservationRecorder.add(this, 'can.patches'); + return this.___get('' + prop); + } else { + return Map.prototype.__get.call(this, prop); + } + }, + ___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)); + }, + 'can.onPatches': function (handler, queue) { + this[canSymbol.for('can.onKeyValue')]('can.patches', handler, queue); + }, + 'can.offPatches': function (handler, queue) { + this[canSymbol.for('can.offKeyValue')]('can.patches', handler, queue); + } + }); + Map.List = List; + module.exports = namespace.List = List; +}); +/*can-list@4.2.2#can-list_test*/ +define('can-list@4.2.2#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'); + QUnit.test('list attr changes length', function (assert) { + var l = new List([ + 0, + 1, + 2 + ]); + l.attr(3, 3); + assert.equal(l.length, 4); + }); + QUnit.test('removeAttr on list', function (assert) { + var l = new List([ + 0, + 1, + 2 + ]); + l.removeAttr(1); + assert.equal(l.attr('length'), 2); + assert.deepEqual(l.attr(), [ + 0, + 2 + ]); + }); + QUnit.test('list splice', function (assert) { + var l = new List([ + 0, + 1, + 2, + 3 + ]), first = true; + l.bind('change', function (ev, attr, how, newVals, oldVals) { + assert.equal(attr, '1'); + if (first) { + assert.equal(how, 'remove', 'removing items'); + assert.equal(newVals, undefined, 'no new Vals'); + } else { + assert.deepEqual(newVals, [ + 'a', + 'b' + ], 'got the right newVals'); + assert.equal(how, 'add', 'adding items'); + } + first = false; + }); + l.splice(1, 2, 'a', 'b'); + assert.deepEqual(l.serialize(), [ + 0, + 'a', + 'b', + 3 + ], 'serialized'); + }); + QUnit.test('list pop', function (assert) { + var l = new List([ + 0, + 1, + 2, + 3 + ]); + l.bind('change', function (ev, attr, how, newVals, oldVals) { + assert.equal(attr, '3'); + assert.equal(how, 'remove'); + assert.equal(newVals, undefined); + assert.deepEqual(oldVals, [3]); + }); + l.pop(); + assert.deepEqual(l.serialize(), [ + 0, + 1, + 2 + ]); + }); + QUnit.test('remove nested property in item of array map', function (assert) { + var state = new List([{ nested: true }]); + state.bind('change', function (ev, attr, how, newVal, old) { + assert.equal(attr, '0.nested'); + assert.equal(how, 'remove'); + assert.deepEqual(old, true); + }); + state.removeAttr('0.nested'); + assert.equal(undefined, state.attr('0.nested')); + }); + QUnit.test('pop unbinds', function (assert) { + 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) { + assert.equal(attr, '0.foo', 'count is set'); + } else if (count === 2) { + assert.equal(how, 'remove'); + assert.equal(attr, '0'); + } else { + assert.ok(false, 'called too many times'); + } + }); + assert.equal(o.attr('foo'), 'bar', 'read foo property'); + o.attr('foo', 'car'); + l.pop(); + o.attr('foo', 'bad'); + }); + QUnit.test('splice unbinds', function (assert) { + 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) { + assert.equal(attr, '0.foo', 'count is set'); + } else if (count === 2) { + assert.equal(how, 'remove'); + assert.equal(attr, '0'); + } else { + assert.ok(false, 'called too many times'); + } + }); + assert.equal(o.attr('foo'), 'bar'); + o.attr('foo', 'car'); + l.splice(0, 1); + o.attr('foo', 'bad'); + }); + QUnit.test('always gets right attr even after moving array items', function (assert) { + var l = new List([{ foo: 'bar' }]); + var o = l.attr(0); + l.unshift('A new Value'); + l.bind('change', function (ev, attr, how) { + assert.equal(attr, '1.foo'); + }); + o.attr('foo', 'led you'); + }); + QUnit.test('Array accessor methods', function (assert) { + assert.expect(11); + var l = new List([ + 'a', + 'b', + 'c' + ]), sliced = l.slice(2), joined = l.join(' | '), concatenated = l.concat([ + 2, + 1 + ], new List([0])); + assert.ok(sliced instanceof List, 'Slice is an Observable list'); + assert.equal(sliced.length, 1, 'Sliced off two elements'); + assert.equal(sliced[0], 'c', 'Single element as expected'); + assert.equal(joined, 'a | b | c', 'Joined list properly'); + assert.ok(concatenated instanceof List, 'Concatenated is an Observable list'); + assert.deepEqual(concatenated.serialize(), [ + 'a', + 'b', + 'c', + 2, + 1, + 0 + ], 'List concatenated properly'); + l.forEach(function (letter, index) { + assert.ok(true, 'Iteration'); + if (index === 0) { + assert.equal(letter, 'a', 'First letter right'); + } + if (index === 2) { + assert.equal(letter, 'c', 'Last letter right'); + } + }); + }); + QUnit.test('Concatenated list items Equal original', function (assert) { + var l = new List([ + { firstProp: 'Some data' }, + { secondProp: 'Next data' } + ]), concatenated = l.concat([ + { hello: 'World' }, + { foo: 'Bar' } + ]); + assert.ok(l[0] === concatenated[0], 'They are Equal'); + assert.ok(l[1] === concatenated[1], 'They are Equal'); + }); + QUnit.test('Lists with maps concatenate properly', function (assert) { + 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); + assert.ok(people.attr('length') === 8, 'List length is right'); + assert.ok(people[0] === me, 'Map in list === vars created before concat'); + assert.ok(people[1] instanceof Person, 'Animal got serialized to Person'); + }); + QUnit.test('splice removes items in IE (#562)', function (assert) { + var l = new List(['a']); + l.splice(0, 1); + assert.ok(!l.attr(0), 'all props are removed'); + }); + QUnit.test('reverse triggers add/remove events (#851)', function (assert) { + assert.expect(6); + var l = new List([ + 1, + 2, + 3 + ]); + l.bind('change', function () { + assert.ok(true, 'change should be called'); + }); + l.bind('set', function () { + assert.ok(false, 'set should not be called'); + }); + l.bind('add', function () { + assert.ok(true, 'add called'); + }); + l.bind('remove', function () { + assert.ok(true, 'remove called'); + }); + l.bind('length', function () { + assert.ok(true, 'length should be called'); + }); + l.reverse(); + }); + QUnit.test('filter', function (assert) { + var l = new List([ + { + id: 1, + name: 'John' + }, + { + id: 2, + name: 'Mary' + } + ]); + var filtered = l.filter(function (item) { + return item.name === 'Mary'; + }); + assert.notEqual(filtered._cid, l._cid, 'not same object'); + assert.equal(filtered.length, 1, 'one item'); + assert.equal(filtered[0].name, 'Mary', 'filter works'); + }); + QUnit.test('removing expandos on lists', function (assert) { + var list = new List([ + 'a', + 'b' + ]); + list.removeAttr('foo'); + assert.equal(list.length, 2); + }); + QUnit.test('No Add Events if List Splice adds the same items that it is removing. (#1277, #1399)', function (assert) { + var list = new List([ + 'a', + 'b' + ]); + list.bind('add', function () { + assert.ok(false, 'Add callback should not be called.'); + }); + list.bind('remove', function () { + assert.ok(false, 'Remove callback should not be called.'); + }); + var result = list.splice(0, 2, 'a', 'b'); + assert.deepEqual(result, [ + 'a', + 'b' + ]); + }); + QUnit.test('add event always returns an array as the value (#998)', function (assert) { + var list = new List([]), msg; + list.bind('add', function (ev, newElements, index) { + assert.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]); + }); + QUnit.test('Setting with .attr() out of bounds of length triggers add event with leading undefineds', function (assert) { + var list = new List([1]); + list.bind('add', function (ev, newElements, index) { + assert.deepEqual(newElements, [ + undefined, + undefined, + 4 + ], 'Leading undefineds are included'); + assert.equal(index, 1, 'Index takes into account the leading undefineds from a .attr()'); + }); + list.attr(3, 4); + }); + QUnit.test('No events should fire if removals happened on empty arrays', function (assert) { + var list = new List([]), msg; + list.bind('remove', function (ev, removed, index) { + assert.ok(false, msg); + }); + msg = 'works on pop'; + list.pop(); + msg = 'works on shift'; + list.shift(); + assert.ok(true, 'No events were fired.'); + }); + QUnit.test('setting an index out of bounds does not create an array', function (assert) { + assert.expect(1); + var l = new List(); + l.attr('1', 'foo'); + assert.equal(l.attr('1'), 'foo'); + }); + QUnit.test('splice with similar but less items works (#1606)', function (assert) { + var list = new List([ + 'aa', + 'bb', + 'cc' + ]); + list.splice(0, list.length, 'aa', 'cc', 'dd'); + assert.deepEqual(list.attr(), [ + 'aa', + 'cc', + 'dd' + ]); + list.splice(0, list.length, 'aa', 'cc'); + assert.deepEqual(list.attr(), [ + 'aa', + 'cc' + ]); + }); + QUnit.test('filter returns same list type (#1744)', function (assert) { + var ParentList = List.extend(); + var ChildList = ParentList.extend(); + var children = new ChildList([ + 1, + 2, + 3 + ]); + assert.ok(children.filter(function () { + }) instanceof ChildList); + }); + QUnit.test('reverse returns the same list instance (#1744)', function (assert) { + var ParentList = List.extend(); + var ChildList = ParentList.extend(); + var children = new ChildList([ + 1, + 2, + 3 + ]); + assert.ok(children.reverse() === children); + }); + QUnit.test('slice and join are observable by a compute (#1884)', function (assert) { + assert.expect(2); + var list = new List([ + 1, + 2, + 3 + ]); + var sliced = new Observation(function () { + return list.slice(0, 1); + }); + canReflect.onValue(sliced, function (newVal) { + assert.deepEqual(newVal.attr(), [2], 'got a new List'); + }); + var joined = new Observation(function () { + return list.join(','); + }); + canReflect.onValue(joined, function (newVal) { + assert.equal(newVal, '2,3', 'joined is observable'); + }); + list.shift(); + }); + QUnit.test('list is always updated with the last promise passed to replace (#2136)', function (assert) { + var list = new List(); + var done = assert.async(); + list.replace(new Promise(function (resolve) { + setTimeout(function () { + resolve(['A']); + setTimeout(function () { + assert.equal(list.attr(0), 'B', 'list set to last promise\'s value'); + done(); + }, 10); + }, 20); + })); + list.replace(new Promise(function (resolve) { + setTimeout(function () { + resolve(['B']); + }, 10); + })); + }); + QUnit.test('forEach callback', function (assert) { + var list = new List([]), counter = 0; + list.attr(9, 'foo'); + list.forEach(function (element, index, list) { + counter++; + }); + assert.equal(counter, 1, 'Should not be invoked for uninitialized attr keys'); + }); + QUnit.test('filter with context', function (assert) { + var l = new List([{ id: 1 }]); + var context = {}; + var contextWasCorrect = false; + l.filter(function () { + contextWasCorrect = this === context; + return true; + }, context); + assert.equal(contextWasCorrect, true, 'context was correctly passed'); + }); + QUnit.test('map with context', function (assert) { + var l = new List([{ id: 1 }]); + var context = {}; + var contextWasCorrect = false; + l.map(function () { + contextWasCorrect = this === context; + return true; + }, context); + assert.equal(contextWasCorrect, true, 'context was correctly passed'); + }); + QUnit.test('works with can-reflect', function (assert) { + assert.expect(11); + var a = new Map({ foo: 4 }); + var b = new List([ + 'foo', + 'bar' + ]); + assert.equal(canReflect.getKeyValue(b, '0'), 'foo', 'unbound value'); + var handler = function (newValue) { + assert.equal(newValue, 'quux', 'observed new value'); + }; + assert.ok(!canReflect.isValueLike(b), 'isValueLike is false'); + assert.ok(canReflect.isMapLike(b), 'isMapLike is true'); + assert.ok(canReflect.isListLike(b), 'isListLike is false'); + assert.ok(!canReflect.keyHasDependencies(b, 'length'), 'keyHasDependencies -- false'); + b._computedAttrs['length'] = { + compute: new Observation(function () { + return a.attr('foo'); + }, null) + }; + b._computedAttrs['length'].compute.start(); + assert.ok(canReflect.keyHasDependencies(b, 'length'), 'keyHasDependencies -- true'); + canReflect.onKeysAdded(b, handler); + canReflect.onKeysRemoved(b, handler); + var handlers = b[canSymbol.for('can.meta')].handlers; + assert.ok(handlers.get(['add']).length, 'add handler added'); + assert.ok(handlers.get(['remove']).length, 'remove handler added'); + b.push('quux'); + assert.equal(canReflect.getKeyValue(b, 'length'), '4', 'bound value'); + b.pop(); + }); + QUnit.test('can-reflect setKeyValue', function (assert) { + var a = new Map({ 'a': 'b' }); + canReflect.setKeyValue(a, 'a', 'c'); + assert.equal(a.attr('a'), 'c', 'setKeyValue'); + }); + QUnit.test('can-reflect getKeyDependencies', function (assert) { + var a = new Map({ foo: 4 }); + var b = new List([ + 'foo', + 'bar' + ]); + assert.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(); + assert.ok(canReflect.getKeyDependencies(b, 'length'), 'dependencies exist'); + assert.ok(canReflect.getKeyDependencies(b, 'length').valueDependencies.has(b._computedAttrs.length.compute), 'dependencies returned'); + }); + QUnit.test('registered symbols', function (assert) { + var a = new Map({ 'a': 'a' }); + assert.ok(a[canSymbol.for('can.isMapLike')], 'can.isMapLike'); + assert.equal(a[canSymbol.for('can.getKeyValue')]('a'), 'a', 'can.getKeyValue'); + a[canSymbol.for('can.setKeyValue')]('a', 'b'); + assert.equal(a.attr('a'), 'b', 'can.setKeyValue'); + function handler(val) { + assert.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 (assert) { + 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) { + assert.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 (assert) { + 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); + assert.deepEqual(calls, [ + [ + list, + [{ + type: 'splice', + index: 2, + deleteCount: 0, + insert: [3] + }] + ], + [ + list, + [{ + type: 'set', + key: 'count', + value: 8 + }] + ] + ]); + }); + QUnit.test('can.onInstanceBoundChange basics', function (assert) { + 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); + assert.deepEqual(calls, [ + [ + people, + true + ], + [ + people, + false + ] + ]); + }); + QUnit.test('list.sort a simple list', function (assert) { + var myList = new List([ + 'Marshall', + 'Austin', + 'Hyrum' + ]); + myList.sort(); + assert.equal(myList.length, 3); + assert.equal(myList[0], 'Austin'); + assert.equal(myList[1], 'Hyrum'); + assert.equal(myList[2], 'Marshall', 'Basic list was properly sorted.'); + }); + QUnit.test('list.sort a list of objects', function (assert) { + 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; + } + }); + assert.equal(objList.length, 3); + assert.equal(objList[0].name, 'Austin'); + assert.equal(objList[1].name, 'Hyrum'); + assert.equal(objList[2].name, 'Marshall', 'List of objects was properly sorted.'); + }); + QUnit.test('list.sort a list of objects without losing reference (#137)', function (assert) { + 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; + }); + assert.equal(unSorted[0], sorted[2], 'items should be equal'); + }); + QUnit.test('list receives patch events', function (assert) { + assert.expect(2); + var list = new List([]); + function handler(patches) { + if (patches[0].index === 0 && patches[0].insert) { + assert.ok(true); + } + } + canReflect.onPatches(list, handler); + list.push('foo'); + list.attr(0, 'bar'); + canReflect.offPatches(list, handler); + }); +}); +/*can-reflect-tests@1.0.0#observables/map-like/type/define-instance-key*/ +define('can-reflect-tests@1.0.0#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 (assert) { + var Type = makeType(); + Type[canSymbol.for('can.defineInstanceKey')]('prop', { + value: 0, + configurable: true, + writable: true, + enumerable: true + }); + var t = new Type(); + assert.equal(canReflect.getKeyValue(t, 'prop'), 0, 'default value used'); + canReflect.setKeyValue(t, 'prop', '5'); + t.prop = '5'; + assert.equal(t.prop, '5', 'value set'); + }); + }; +}); +/*can-reflect-tests@1.0.0#observables/map-like/type/define-instance-key-enumerable*/ +define('can-reflect-tests@1.0.0#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 (assert) { + 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(); + assert.equal(canReflect.getKeyValue(t, 'nonEnum'), 0, 'default value used'); + canReflect.setKeyValue(t, 'prop', '5'); + t.prop = '5'; + assert.equal(t.prop, '5', 'value set'); + assert.deepEqual(canReflect.serialize(t), { prop: '5' }, 'enumerable respected'); + }); + }; +}); +/*can-reflect-tests@1.0.0#observables/map-like/type/on-instance-bound-change*/ +define('can-reflect-tests@1.0.0#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 (assert) { + 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); + assert.deepEqual(calls, [ + [ + instance, + true + ], + [ + instance, + false + ] + ]); + }); + }; +}); +/*can-reflect-tests@1.0.0#observables/map-like/type/on-instance-patches*/ +define('can-reflect-tests@1.0.0#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 (assert) { + 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'); + assert.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@1.0.0#observables/map-like/type/type*/ +define('can-reflect-tests@1.0.0#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-map@4.3.9#can-map_test*/ +define('can-map@4.3.9#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-test-helpers', + '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'); + var testHelpers = require('can-test-helpers'); + QUnit.module('can-map'); + QUnit.test('Basic Map', function (assert) { + assert.expect(4); + var state = new Map({ + category: 5, + productType: 4 + }); + state.bind('change', function (ev, attr, how, val, old) { + assert.equal(attr, 'category', 'correct change name'); + assert.equal(how, 'set'); + assert.equal(val, 6, 'correct'); + assert.equal(old, 5, 'correct'); + }); + state.attr('category', 6); + state.unbind('change'); + }); + QUnit.test('Nested Map', function (assert) { + assert.expect(5); + var me = new Map({ + name: { + first: 'Justin', + last: 'Meyer' + } + }); + assert.ok(me.attr('name') instanceof Map); + me.bind('change', function (ev, attr, how, val, old) { + assert.equal(attr, 'name.first', 'correct change name'); + assert.equal(how, 'set'); + assert.equal(val, 'Brian', 'correct'); + assert.equal(old, 'Justin', 'correct'); + }); + me.attr('name.first', 'Brian'); + me.unbind('change'); + }); + QUnit.test('remove attr', function (assert) { + var state = new Map({ + category: 5, + productType: 4 + }); + state.removeAttr('category'); + assert.deepEqual(Map.keys(state), ['productType'], 'one property'); + }); + QUnit.test('remove attr on key with dot', function (assert) { + 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'); + assert.deepEqual(Map.keys(state), ['productType'], 'one property'); + assert.deepEqual(Map.keys(state2), [ + 'key.with.dots', + 'key' + ], 'two properties'); + assert.deepEqual(Map.keys(state2.key['with']), [], 'zero properties'); + }); + QUnit.test('nested event handlers are not run by changing the parent property (#280)', function (assert) { + var person = new Map({ name: { first: 'Justin' } }); + person.bind('name.first', function (ev, newName) { + assert.ok(false, 'name.first should never be called'); + }); + person.bind('name', function () { + assert.ok(true, 'name event triggered'); + }); + person.attr('name', { first: 'Hank' }); + }); + QUnit.test('cyclical objects (#521)', function (assert) { + var foo = {}; + foo.foo = foo; + var fooed = new Map(foo); + assert.ok(true, 'did not cause infinate recursion'); + assert.ok(fooed.attr('foo') === fooed, 'map points to itself'); + var me = { name: 'Justin' }; + var references = { + husband: me, + friend: me + }; + var ref = new Map(references); + assert.ok(ref.attr('husband') === ref.attr('friend'), 'multiple properties point to the same thing'); + }); + QUnit.test('_cid add to original object', function (assert) { + var map = new Map(), obj = { 'name': 'thecountofzero' }; + map.attr('myObj', obj); + assert.ok(!obj._cid, '_cid not added to original object'); + }); + QUnit.test('Map serialize triggers reading (#626)', function (assert) { + 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(); + assert.ok(attributesRead.indexOf('cats') !== -1 && attributesRead.indexOf('dogs') !== -1, 'map serialization triggered __reading on all attributes'); + assert.ok(readingTriggeredForKeys, 'map serialization triggered __reading for __keys'); + ObservationRecorder.add = old; + }); + QUnit.test('Test top level attributes', function (assert) { + assert.expect(7); + var test = new Map({ + 'my.enable': false, + 'my.item': true, + 'my.count': 0, + 'my.newCount': 1, + 'my': { + 'value': true, + 'nested': { 'value': 100 } + } + }); + assert.equal(test.attr('my.value'), true, 'correct'); + assert.equal(test.attr('my.nested.value'), 100, 'correct'); + assert.ok(test.attr('my.nested') instanceof Map); + assert.equal(test.attr('my.enable'), false, 'falsey (false) value accessed correctly'); + assert.equal(test.attr('my.item'), true, 'truthey (true) value accessed correctly'); + assert.equal(test.attr('my.count'), 0, 'falsey (0) value accessed correctly'); + assert.equal(test.attr('my.newCount'), 1, 'falsey (1) value accessed correctly'); + }); + QUnit.test('serializing cycles', function (assert) { + var map1 = new Map({ name: 'map1' }); + var map2 = new Map({ name: 'map2' }); + map1.attr('map2', map2); + map2.attr('map1', map1); + var res = map1.serialize(); + assert.equal(res.name, 'map1'); + assert.equal(res.map2.name, 'map2'); + }); + QUnit.test('Unbinding from a map with no bindings doesn\'t throw an error (#1015)', function (assert) { + assert.expect(0); + var test = new Map({}); + try { + test.unbind('change'); + } catch (e) { + assert.ok(false, 'No error should be thrown'); + } + }); + QUnit.test('Fast dispatch event still has target and type (#1082)', function (assert) { + assert.expect(4); + var data = new Map({ name: 'CanJS' }); + data.bind('change', function (ev) { + assert.equal(ev.type, 'change'); + assert.equal(ev.target, data); + }); + data.bind('name', function (ev) { + assert.equal(ev.type, 'name'); + assert.equal(ev.target, data); + }); + data.attr('name', 'David'); + }); + QUnit.test('map passed to Map constructor (#1166)', function (assert) { + function y() { + } + var map = new Map({ + x: 1, + y: y + }); + var res = new Map(map); + assert.deepEqual(res.attr(), { + x: 1, + y: y + }, 'has the same properties'); + }); + QUnit.test('constructor passed to scope is threated as a property (#1261)', function (assert) { + var Constructor = Construct.extend({}); + var MyMap = Map.extend({ Todo: Constructor }); + var m = new MyMap(); + assert.equal(m.attr('Todo'), Constructor); + }); + QUnit.test('_bindings count maintained after calling .off() on undefined property (#1490) ', function (assert) { + var map = new Map({ test: 1 }); + map.on('test', function () { + }); + var handlers = map[canSymbol.for('can.meta')].handlers; + assert.equal(handlers.get([]).length, 1, 'The number of bindings is correct'); + map.off('undefined_property'); + assert.equal(handlers.get([]).length, 1, 'The number of bindings is still correct'); + }); + QUnit.test('Should be able to get and set attribute named \'watch\' on Map in Firefox', function (assert) { + var map = new Map({}); + map.attr('watch'); + assert.ok(true, 'can have attribute named \'watch\' on a Map instance'); + }); + QUnit.test('Should be able to get and set attribute named \'unwatch\' on Map in Firefox', function (assert) { + var map = new Map({}); + map.attr('unwatch'); + assert.ok(true, 'can have attribute named \'unwatch\' on a Map instance'); + }); + QUnit.test('should get an empty string property value correctly', function (assert) { + var map = new Map({ + foo: 'foo', + '': 'empty string' + }); + assert.equal(map.attr(''), 'empty string'); + }); + QUnit.test('ObserveReader - can.Construct derived classes should be considered objects, not functions (#450)', function (assert) { + 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')); + assert.equal(read.value, 'bar', 'static properties on a can.Construct-based function'); + read = observeReader.read(obj, observeReader.reads('next_level.thing.self'), { isArgument: true }); + assert.ok(read.value === foostructor, 'arguments shouldn\'t be executed'); + }); + QUnit.test('works with can-reflect', function (assert) { + assert.expect(7); + var b = new Map({ 'foo': 'bar' }); + var c = new (Map.extend({ + 'baz': canCompute(function () { + return b.attr('foo'); + }) + }))({ + 'foo': 'bar', + thud: 'baz' + }); + assert.equal(canReflect.getKeyValue(b, 'foo'), 'bar', 'unbound value'); + function bazHandler(newValue) { + assert.equal(newValue, 'quux', 'observed new value on baz'); + canReflect.offKeyValue(c, 'baz', bazHandler); + } + function thudHandler(newValue) { + assert.equal(newValue, 'quux', 'observed new value on thud'); + canReflect.offKeyValue(c, 'thud', thudHandler); + } + assert.ok(!canReflect.isValueLike(c), 'isValueLike is false'); + assert.ok(canReflect.isMapLike(c), 'isMapLike is true'); + assert.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'); + assert.equal(canReflect.getKeyValue(c, 'baz'), 'quux', 'bound value'); + b.attr('foo', 'thud'); + c.attr('baz', 'jeek'); + }); + QUnit.test('onKeyValue and queues', function (assert) { + 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(); + assert.deepEqual(order, [ + 'onKeyValue', + 'mutate' + ]); + }); + QUnit.test('can-reflect setKeyValue', function (assert) { + var a = new Map({ 'a': 'b' }); + canReflect.setKeyValue(a, 'a', 'c'); + assert.equal(a.attr('a'), 'c', 'setKeyValue'); + }); + QUnit.test('can-reflect getKeyDependencies', function (assert) { + var a = new Map({ 'a': 'a' }); + var b = new (Map.extend({ + 'a': canCompute(function () { + return a.attr('a'); + }), + 'b': 'b' + }))(); + assert.ok(canReflect.getKeyDependencies(b, 'a'), 'Dependencies on computed attr'); + assert.ok(!canReflect.getKeyDependencies(b, 'b'), 'No dependencies on data attr'); + b.on('a', function () { + }); + assert.ok(canReflect.getKeyDependencies(b, 'a').valueDependencies.has(b._computedAttrs.a.compute), 'dependencies returned'); + assert.ok(canReflect.getValueDependencies(b._computedAttrs.a.compute).valueDependencies, 'dependencies returned from compute'); + }); + QUnit.test('registered symbols', function (assert) { + var a = new Map({ 'a': 'a' }); + assert.ok(a[canSymbol.for('can.isMapLike')], 'can.isMapLike'); + assert.equal(a[canSymbol.for('can.getKeyValue')]('a'), 'a', 'can.getKeyValue'); + a[canSymbol.for('can.setKeyValue')]('a', 'b'); + assert.equal(a.attr('a'), 'b', 'can.setKeyValue'); + function handler(val) { + assert.equal(this, a); + assert.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 (assert) { + var Person = Map.extend({ + first: 'any', + last: 'any' + }); + var p = new Person(); + assert.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 (assert) { + 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; + assert.equal(changes, 1, 'caused a change event'); + assert.equal(myMap1Instance.attr('prop1'), map2, 'overwrite with maps'); + }); + QUnit.test('.attr() leaves typed instances alone if _legacyAttrBehavior is true (#111)', function (assert) { + 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) }); + assert.equal(myMap.attr().myClass, myMap.attr('myClass')); + delete Map.prototype._legacyAttrBehavior; + }); + QUnit.test('.serialize() leaves typed instances alone if _legacyAttrBehavior is true', function (assert) { + function MyClass(value) { + this.value = value; + } + var myMap = new Map({ + _legacyAttrBehavior: true, + myClass: new MyClass('foo') + }); + var ser = myMap.serialize(); + assert.equal(ser.myClass, myMap.attr('myClass')); + }); + QUnit.test('keys with undefined values should not be dropped (#118)', function (assert) { + var obj1 = { 'keepMe': undefined }; + var map = new Map(obj1); + map.attr('foo', undefined); + var keys = Map.keys(map); + assert.deepEqual(keys, [ + 'keepMe', + 'foo' + ]); + }); + QUnit.test('Can assign nested properties that are not CanMaps', function (assert) { + 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' + } + }); + assert.equal(map.attr('prop.one'), '1'); + assert.equal(map.attr('prop.two'), '2'); + assert.equal(map.attr('prop.three'), 'three'); + map.attr({ + prop: { + one: 'one', + two: 'two' + } + }, true); + assert.equal(map.attr('prop.one'), 'one'); + assert.equal(map.attr('prop.two'), 'two'); + assert.equal(map.attr('prop.three'), undefined); + }); + testHelpers.dev.devOnlyTest('warning when setting during a get', function (assert) { + var msg = /.* This can cause infinite loops and performance issues.*/; + var teardownWarn = testHelpers.dev.willWarn(msg, function (text, match) { + if (match) { + assert.ok(true, 'warning fired'); + } + }); + var noop = function () { + }; + var Type = Map.extend('Type', { + prop: '', + prop2: '' + }); + var inst = new Type(); + var Type2 = Map.extend('Type2', { + baz: canCompute(function getterThatWrites() { + inst.attr('prop', 'foo'); + return inst.attr('prop2'); + }) + }); + var obs = new Type2(); + canReflect.setName(Type2.prototype.baz, 'a test observation'); + obs.on('baz', noop); + inst.attr('prop2', 'bar'); + assert.equal(teardownWarn(), 1, 'warning correctly generated'); + teardownWarn = testHelpers.dev.willWarn(msg, function (text, match) { + if (match) { + assert.ok(false, 'warning incorrectly fired'); + } + }); + obs.off('baz', noop); + inst.attr('prop2', 'baz'); + teardownWarn(); + }); + testHelpers.dev.devOnlyTest('warning when setting during a get (batched)', function (assert) { + var msg = /.* This can cause infinite loops and performance issues.*/; + var teardownWarn = testHelpers.dev.willWarn(msg, function (text, match) { + if (match) { + assert.ok(true, 'warning fired'); + } + }); + var noop = function () { + }; + var Type = Map.extend('Type', { + prop: '', + prop2: '' + }); + var inst = new Type(); + queues.batch.start(); + var Type2 = Map.extend('Type2', { + baz: canCompute(function getterThatWrites() { + inst.attr('prop', 'foo'); + return inst.attr('prop2'); + }) + }); + var obs = new Type2(); + canReflect.setName(Type2.prototype.baz, 'a test observation'); + obs.on('baz', noop); + inst.attr('prop2', 'bar'); + queues.batch.stop(); + assert.equal(teardownWarn(), 1, 'warning correctly generated'); + teardownWarn = testHelpers.dev.willWarn(msg, function (text, match) { + if (match) { + assert.ok(false, 'warning incorrectly fired'); + } + }); + obs.off('baz', noop); + queues.batch.start(); + inst.attr('prop2', 'baz'); + queues.batch.stop(); + teardownWarn(); + }); +}); +/*can-map-define@4.4.0#can-map-define*/ +define('can-map-define@4.4.0#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-simple-observable/resolver/resolver', + 'can-symbol', + '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'); + var Resolver = require('can-simple-observable/resolver/resolver'); + var canSymbol = require('can-symbol'); + require('can-list'); + var define = {}; + var inSetupSymbol = canSymbol.for('can.initializing'); + 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)); + } + if (def.resolver) { + mapHelpers.addComputedAttr(this, attr, new Resolver(def.resolver, this, def.value)); + } + } + }; + 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[inSetupSymbol]) { + 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.4.0#can-map-define_test*/ +define('can-map-define@4.4.0#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 (assert) { + var Defined = CanMap.extend({ + define: { + prop: { + set: function (newVal) { + return 'foo' + newVal; + } + } + } + }); + var def = new Defined(); + def.attr('prop', 'bar'); + assert.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'); + assert.equal(def.attr('prop'), 'foobar', 'setter callback works'); + }); + QUnit.test('basics remove', function (assert) { + 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; + } + assert.equal(attr, events[eventCount++], 'got correct attribute'); + assert.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 (assert) { + assert.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(); + assert.deepEqual(CanMap.keys(t), [ + 'arrayWithAddedItem', + 'listWithAddedItem' + ], 'defined keys'); + var array = []; + t.attr('arrayWithAddedItem', array); + assert.deepEqual(array, ['item'], 'updated array'); + assert.equal(t.attr('arrayWithAddedItem'), array, 'leave value as array'); + t.attr('listWithAddedItem', []); + assert.ok(t.attr('listWithAddedItem') instanceof List, 'convert to List'); + assert.equal(t.attr('listWithAddedItem').attr(0), 'item', 'has item in it'); + t.bind('change', function (ev, attr) { + assert.equal(attr, 'listWithAddedItem.1', 'got a bubbling event'); + }); + t.attr('listWithAddedItem').push('another item'); + }); + QUnit.test('basic Type', function (assert) { + 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' }); + assert.equal(t.attr('foo').getName(), 'Justin', 'correctly created an instance'); + var brian = new Foo('brian'); + t.attr('foo', brian); + assert.equal(t.attr('foo'), brian, 'same instances'); + }); + QUnit.test('type converters', function (assert) { + 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 + }); + assert.ok(t.attr('date') instanceof Date, 'converted to date'); + assert.equal(t.attr('string'), '5', 'converted to string'); + assert.equal(t.attr('number'), 5, 'converted to number'); + assert.equal(t.attr('boolean'), false, 'converted to boolean'); + assert.equal(t.attr('htmlbool'), true, 'converted to htmlbool'); + assert.equal(t.attr('leaveAlone'), obj, 'left as object'); + t.attr({ 'number': '15' }); + assert.ok(t.attr('number') === 15, 'converted to number'); + }); + QUnit.test('basics value', function (assert) { + var Typer = CanMap.extend({ define: { prop: { value: 'foo' } } }); + assert.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(); + assert.ok(t1.attr('prop') !== t2.attr('prop'), 'different array instances'); + assert.ok(Array.isArray(t1.attr('prop')), 'its an array'); + }); + QUnit.test('basics Value', function (assert) { + var Typer = CanMap.extend({ + define: { + prop: { + Value: Array, + type: '*' + } + } + }); + var t1 = new Typer(), t2 = new Typer(); + assert.ok(t1.attr('prop') !== t2.attr('prop'), 'different array instances'); + assert.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 (assert) { + var Typer = CanMap.extend({ + define: { + prop: { + set: function () { + this.attr('foo', 'bar'); + } + } + } + }); + var t = new Typer(); + t.attr('prop', false); + assert.deepEqual(t.attr(), { + foo: 'bar', + prop: false + }); + }); + QUnit.test('type happens before the set', function (assert) { + var MyMap = CanMap.extend({ + define: { + prop: { + type: 'number', + set: function (newValue) { + assert.equal(typeof newValue, 'number', 'got a number'); + return newValue + 1; + } + } + } + }); + var map = new MyMap(); + map.attr('prop', '5'); + assert.equal(map.attr('prop'), 6, 'number'); + }); + QUnit.test('getter and setter work', function (assert) { + assert.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 + }); + assert.equal(p.attr('page'), 3, 'page get right'); + p.bind('page', function (ev, newValue, oldValue) { + assert.equal(newValue, 2, 'got new value event'); + assert.equal(oldValue, 3, 'got old value event'); + }); + p.attr('page', 2); + assert.equal(p.attr('page'), 2, 'page set right'); + assert.equal(p.attr('offset'), 10, 'page offset set'); + }); + QUnit.test('getter with initial value', function (assert) { + 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(); + assert.equal(g.attr('vals').length, 0, 'zero items in array'); + }); + QUnit.test('serialize basics', function (assert) { + 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' + } + ]); + assert.equal(map.attr('locationIds').length, 2, 'get locationIds'); + assert.equal(map.attr('locationIds')[0], 1, 'get locationIds index 0'); + assert.equal(map.attr('locations')[0].id, 1, 'get locations index 0'); + var serialized = map.serialize(); + assert.equal(serialized.locations, undefined, 'locations doesn\'t serialize'); + assert.equal(serialized.locationIds, '1,2', 'locationIds serializes'); + assert.equal(serialized.name, undefined, 'name doesn\'t serialize'); + assert.equal(serialized.bared, 'foo+bar', 'true adds computed props'); + assert.equal(serialized.ignored, undefined, 'computed props are not serialized by default'); + }); + QUnit.test('serialize context', function (assert) { + 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(); + assert.equal(context, map); + assert.equal(serializeContext, map); + }); + QUnit.test('methods contexts', function (assert) { + 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'); + assert.equal(contexts.get, map); + assert.equal(contexts.remove, map); + assert.equal(contexts.set, map); + assert.equal(contexts.serialize, map); + assert.equal(contexts.type, map); + }); + QUnit.test('value generator is not called if default passed', function (assert) { + var TestMap = CanMap.extend({ + define: { + foo: { + value: function () { + throw '"foo"\'s value method should not be called.'; + } + } + } + }); + var tm = new TestMap({ foo: 'baz' }); + assert.equal(tm.attr('foo'), 'baz'); + }); + QUnit.test('Value generator can read other properties', function (assert) { + 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 '; + assert.equal(map.attr('firstLetter'), 'A', prefix + 'traditional CanMap style property definition'); + assert.equal(map.attr('firstNumber'), 1, prefix + 'traditional CanMap style property definition'); + assert.equal(map.attr('middleLetter'), 'E', prefix + 'define plugin style default property definition'); + assert.equal(map.attr('middleNumber'), 5, prefix + 'define plugin style default property definition'); + assert.equal(map.attr('lastLetter'), 'I', prefix + 'define plugin style generated default property definition'); + assert.equal(map.attr('lastNumber'), 9, prefix + 'define plugin style generated default property definition'); + }); + QUnit.test('default behaviors with "*" work for attributes', function (assert) { + assert.expect(9); + var DefaultMap = CanMap.extend({ + define: { + someNumber: { value: '5' }, + '*': { + type: 'number', + serialize: function (value) { + return '' + value; + }, + set: function (newVal) { + assert.ok(true, 'set called'); + return newVal; + }, + remove: function (currentVal) { + assert.ok(true, 'remove called'); + return false; + } + } + } + }); + var map = new DefaultMap(), serializedMap; + assert.equal(map.attr('someNumber'), 5, 'value of someNumber should be converted to a number'); + map.attr('number', '10'); + assert.equal(map.attr('number'), 10, 'value of number should be converted to a number'); + map.removeAttr('number'); + assert.equal(map.attr('number'), 10, 'number should not be removed'); + serializedMap = map.serialize(); + assert.equal(serializedMap.number, '10', 'number serialized as string'); + assert.equal(serializedMap.someNumber, '5', 'someNumber serialized as string'); + assert.equal(serializedMap['*'], undefined, '"*" is not a value in serialized object'); + }); + QUnit.test('models properly serialize with default behaviors', function (assert) { + 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(); + assert.equal(serializedMap.age, undefined, 'age doesn\'t exist'); + assert.equal(serializedMap.name, undefined, 'name doesn\'t exist'); + assert.equal(serializedMap.shirt, 'blue', 'shirt exists'); + }); + QUnit.test('nested define', function (assert) { + 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(); + assert.equal(nested.attr('test.name'), nailedIt); + assert.equal(nested.attr('examples.one.name'), nailedIt); + assert.equal(nested.attr('examples.two.deep.name'), nailedIt); + assert.ok(nested.attr('test') instanceof Example); + assert.ok(nested.attr('examples.one') instanceof Example); + assert.ok(nested.attr('examples.two.deep') instanceof Example); + }); + QUnit.test('Can make an attr alias a compute (#1470)', function (assert) { + assert.expect(9); + 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); + assert.equal(getMap.attr('value'), 1); + var bindCallbacks = 0; + getMap.bind('value', function (ev, newVal, oldVal) { + switch (bindCallbacks) { + case 0: + assert.equal(newVal, 2, '0 - bind called with new val'); + assert.equal(oldVal, 1, '0 - bind called with old val'); + break; + case 1: + assert.equal(newVal, 3, '1 - bind called with new val'); + assert.equal(oldVal, 2, '1 - bind called with old val'); + break; + case 2: + assert.equal(newVal, 4, '2 - bind called with new val'); + assert.equal(oldVal, 3, '2 - bind called with old val'); + break; + } + bindCallbacks++; + }); + computeValue(2); + getMap.attr('value', 3); + assert.equal(getMap.attr('value'), 3, 'read value is 3'); + assert.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 (assert) { + 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 + }; + assert.equal(newVal, expectedNewVal, sub(message, subs)); + subs.prop = 'oldVal'; + assert.equal(oldVal, expectedOldVal, sub(message, subs)); + }; + }; + var ComputableMap = CanMap.extend({ define: { computed: { type: 'compute' } } }); + var computed = compute(0); + var m1 = new ComputableMap({ computed: computed }); + assert.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 (assert) { + var compute1 = compute(0); + var compute2 = compute(1); + var ComputableMap = CanMap.extend({ define: { computable: { type: 'compute' } } }); + var m = new ComputableMap(); + m.attr('computable', compute1); + assert.equal(m.attr('computable'), 0, 'compute1 readable via .attr()'); + m.attr('computable', compute2); + assert.equal(m.attr('computable'), 1, 'compute2 readable via .attr()'); + }); + QUnit.test('value and get (#1521)', function (assert) { + 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({}); + assert.equal(map.attr('size'), 2); + }); + QUnit.test('One event on getters (#1585)', function (assert) { + 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' })); + assert.equal(personEvents, 2); + }); + QUnit.test('Can read a defined property with a set/get method (#1648)', function (assert) { + var Map = CanMap.extend({ + define: { + foo: { + value: '', + set: function (setVal) { + return setVal; + }, + get: function (lastSetVal) { + return lastSetVal; + } + } + } + }); + var map = new Map(); + assert.equal(map.attr('foo'), '', 'Calling .attr(\'foo\') returned the correct value'); + map.attr('foo', 'baz'); + assert.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)', function (assert) { + assert.expect(3); + 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 () { + assert.ok(true, 'Bound function is called'); + }); + assert.equal(map.attr('foo'), '', 'Calling .attr(\'foo\') returned the correct value'); + map.attr('foo', 'baz'); + assert.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 (assert) { + 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 + }); + assert.equal(t.attr('date'), undefined, 'converted to date'); + assert.equal(t.attr('string'), undefined, 'converted to string'); + assert.equal(t.attr('number'), undefined, 'converted to number'); + assert.equal(t.attr('boolean'), undefined, 'converted to boolean'); + assert.equal(t.attr('htmlbool'), false, 'converted to htmlbool'); + assert.equal(t.attr('leaveAlone'), undefined, 'left as object'); + t = new Typer().attr({ + date: null, + string: null, + number: null, + 'boolean': null, + htmlbool: null, + leaveAlone: null + }); + assert.equal(t.attr('date'), null, 'converted to date'); + assert.equal(t.attr('string'), null, 'converted to string'); + assert.equal(t.attr('number'), null, 'converted to number'); + assert.equal(t.attr('boolean'), null, 'converted to boolean'); + assert.equal(t.attr('htmlbool'), false, 'converted to htmlbool'); + assert.equal(t.attr('leaveAlone'), null, 'left as object'); + }); + QUnit.test('Initial value does not call getter', function (assert) { + assert.expect(0); + var Map = CanMap.extend({ + define: { + count: { + get: function (lastVal) { + assert.ok(false, 'Should not be called'); + return lastVal; + } + } + } + }); + new Map({ count: 100 }); + }); + QUnit.test('getters produce change events', function (assert) { + var Map = CanMap.extend({ + define: { + count: { + get: function (lastVal) { + return lastVal; + } + } + } + }); + var map = new Map(); + map.bind('change', function () { + assert.ok(true, 'change called'); + }); + map.attr('count', 22); + }); + QUnit.test('Asynchronous virtual properties cause extra recomputes (#1915)', function (assert) { + var done = assert.async(); + 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) { + assert.ok(false, 'Getter ran twice'); + } + ran = true; + return foo * 2; + } + } + } + } + }); + var vm = new VM(); + vm.bind('bar', function () { + }); + setTimeout(function () { + assert.equal(vm.attr('bar'), 10); + done(); + }, 200); + }); + QUnit.test('double get in a compute (#2230)', function (assert) { + var VM = CanMap.extend({ + define: { + names: { + get: function (val, setVal) { + assert.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 (assert) { + 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 () { + }); + assert.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)', function (assert) { + assert.expect(4); + 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) { + assert.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(); + assert.equal(map.attr('propC'), string2, 'props only in the child have the correct values'); + assert.equal(map.attr('propB'), string2, 'props in both have the child values'); + assert.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 (assert) { + 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(); + assert.equal(map.propC, string2, 'props only in the child have the correct values'); + assert.equal(map.propB, string2, 'props in both have the child values'); + assert.equal(map.propA, string1, 'props only in the parent have the correct values'); + }); + QUnit.test('can inherit object values from another map (#2)', function (assert) { + 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(); + assert.equal(map.attr('propC'), object2, 'props only in the child have the correct values'); + assert.equal(map.attr('propB'), object2, 'props in both have the child values'); + assert.equal(map.attr('propA'), object1, 'props only in the parent have the correct values'); + }); + QUnit.test('can set properties to undefined', function (assert) { + var MyMap = CanMap.extend({ + define: { + foo: { + set: function (newVal) { + return newVal; + } + } + } + }); + var map = new MyMap(); + map.attr('foo', 'bar'); + assert.equal(map.attr('foo'), 'bar', 'foo should be bar'); + map.attr('foo', undefined); + assert.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 (assert) { + var MyMap = CanMap.extend({ + define: { + propA: { + value: function () { + return 1; + } + } + } + }); + var map = new MyMap(); + assert.equal(MyMap.defaults.propA, undefined, 'Generator function does not result in property set on defaults'); + assert.notEqual(MyMap.defaultGenerators.propA, undefined, 'Generator function set on defaultGenerators'); + assert.equal(map.attr('propA'), 1, 'Instance value set properly'); + }); + QUnit.test('can.hasKey', function (assert) { + 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(); + assert.equal(canReflect.hasKey(vm, 'prop'), true, 'vm.hasKey(\'prop\') true'); + assert.equal(canReflect.hasKey(vm, 'derivedProp'), true, 'vm.hasKey(\'derivedProp\') true'); + assert.equal(canReflect.hasKey(vm, 'parentProp'), true, 'vm.hasKey(\'parentProp\') true'); + assert.equal(canReflect.hasKey(vm, 'parentDerivedProp'), true, 'vm.hasKey(\'parentDerivedProp\') true'); + assert.equal(canReflect.hasKey(vm, 'anotherProp'), false, 'vm.hasKey(\'anotherProp\') false'); + assert.equal(canReflect.hasKey(vm, 'aFunction'), true, 'vm.hasKey(\'aFunction\') true'); + assert.equal(canReflect.hasKey(vm, 'parentFunction'), true, 'vm.hasKey(\'parentFunction\') true'); + vm.attr('lateProp', 'something'); + assert.equal(canReflect.hasKey(vm, 'lateProp'), true, 'vm.hasKey(\'lateProp\') true'); + }); + QUnit.test('can.getOwnEnumerableKeys', 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: { + notEnumerable: { + serialize: false, + value: 'no' + }, + enumerableProp: { + serialize: true, + value: 'yes' + }, + enumByDefault: { value: 'maybe' }, + enumGetter: { + get: function () { + return 'got'; + } + } + } + }); + var vm = new VM(); + assert.deepEqual(canReflect.getOwnEnumerableKeys(vm), [ + 'enumerableProp', + 'enumByDefault', + 'parentEnum', + 'parentEnumByDefault' + ], 'vm.getOwnEnumerableKeys()'); + vm.attr('lateProp', true); + assert.deepEqual(canReflect.getOwnEnumerableKeys(vm), [ + 'enumerableProp', + 'enumByDefault', + 'parentEnum', + 'parentEnumByDefault', + 'lateProp' + ], 'vm.getOwnEnumerableKeys() with late prop'); + }); + QUnit.test('can.getOwnEnumerableKeys works without define (#81)', function (assert) { + var VM = CanMap.extend({}); + var vm = new VM({ foo: 'bar' }); + assert.deepEqual(canReflect.getOwnEnumerableKeys(vm), ['foo'], 'without define'); + vm.attr('abc', 'xyz'); + assert.deepEqual(canReflect.getOwnEnumerableKeys(vm), [ + 'foo', + 'abc' + ], 'without define, with late prop'); + VM = CanMap.extend({ define: {} }); + vm = new VM({ foo: 'bar' }); + assert.deepEqual(canReflect.getOwnEnumerableKeys(vm), ['foo'], 'with empty define'); + vm.attr('abc', 'xyz'); + assert.deepEqual(canReflect.getOwnEnumerableKeys(vm), [ + 'foo', + 'abc' + ], 'with empty define, with late prop'); + }); + QUnit.test('can.getOwnEnumerableKeys works with null', function (assert) { + var VM = CanMap.extend({}); + var vm = new VM({ foo: null }); + assert.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'); + }); + QUnit.test('resolver behavior: with counter (#96)', function (assert) { + var Person = CanMap.extend('Person', { + define: { + name: { type: 'string' }, + nameChangedCount: { + resolver: function (prop) { + var count = prop.resolve(0); + prop.listenTo('name', function () { + prop.resolve(++count); + }); + } + } + } + }); + var me = new Person(); + assert.equal(me.attr('nameChangedCount'), 0, 'unbound value'); + me.attr('name', 'first'); + assert.equal(me.attr('nameChangedCount'), 0, 'unbound value'); + me.on('nameChangedCount', function (ev, newVal, oldVal) { + assert.equal(newVal, 1, 'updated count'); + assert.equal(oldVal, 0, 'updated count from old value'); + }); + me.attr('name', 'second'); + assert.equal(me.attr('nameChangedCount'), 1, 'bound value'); + }); +}); +/*can-fixture@3.1.7#data-from-url*/ +define('can-fixture@3.1.7#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.1.7#matches*/ +define('can-fixture@3.1.7#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.1.7#test/matches-test*/ +define('can-fixture@3.1.7#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 (assert) { + var same = matches.request({ url: '/thingers/5' }, { url: '/thingers/{id}' }); + assert.ok(same, 'they are similar'); + same = matches.request({ url: '/thingers/5' }, { url: '/thingers' }); + assert.ok(!same, 'they are not the same'); + }); + QUnit.test('core.matches', function (assert) { + var same = matches.matches({ url: '/thingers/5' }, { url: '/thingers/{id}' }); + assert.ok(same, 'similar'); + same = matches.matches({ + url: '/thingers/5', + type: 'get' + }, { url: '/thingers/{id}' }); + assert.ok(same, 'similar with extra pops on settings'); + var exact = matches.matches({ + url: '/thingers/5', + type: 'get' + }, { url: '/thingers/{id}' }, true); + assert.ok(!exact, 'not exact'); + exact = matches.matches({ url: '/thingers/5' }, { url: '/thingers/5' }, true); + assert.ok(exact, 'exact'); + }); +}); +/*can-memory-store@1.0.2#make-simple-store*/ +define('can-memory-store@1.0.2#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.2#can-memory-store*/ +define('can-memory-store@1.0.2#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.1.7#store*/ +define('can-fixture@3.1.7#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, idType = 'number'; + baseItems.forEach(function (item) { + items.push(canReflect.serialize(item)); + var type = typeof item[idProp]; + if (type === 'number') { + maxId = Math.max(item[idProp], maxId); + } else { + idType = type; + } + }); + return { + maxId: maxId, + items: items, + idType: idType + }; + }; + }; + 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 idType = this.idType; + var identityKey = schema.identity[0], keys = schema.keys; + if (!keys || !keys[identityKey]) { + keys = {}; + keys[identityKey] = function (value) { + if (idType === 'string') { + return '' + value; + } else { + return typeof value === 'string' ? stringToAny(value) : value; + } + }; + } + var copy = {}; + canReflect.eachKey(data, function (value, key) { + if (keys[key]) { + copy[key] = canReflect.serialize(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.idType = itemData.idType; + 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.1.7#core*/ +define('can-fixture@3.1.7#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); + var oldFixture; + if (index > -1) { + oldFixture = fixtures.splice(index, 1); + } + if (fixture == null) { + return oldFixture; + } + if (typeof fixture === 'object') { + var data = fixture; + fixture = function () { + return data; + }; + } + settings.fixture = fixture; + fixtures.unshift(settings); + return oldFixture; + } + exports.add = function (settings, fixture) { + if (fixture === undefined) { + var oldFixtures = []; + if (Array.isArray(settings)) { + canReflect.eachIndex(settings, function (ajaxSettings) { + var fixture = ajaxSettings.fixture; + ajaxSettings = canReflect.assignMap({}, ajaxSettings); + delete ajaxSettings.fixture; + return exports.add(ajaxSettings, fixture); + }); + } else { + canReflect.eachKey(settings, function (fixture, url) { + oldFixtures = oldFixtures.concat(exports.add(url, fixture)); + }); + return oldFixtures; + } + } + if (isStoreLike(fixture)) { + settings = addStoreFixture(settings, fixture); + return exports.add(settings); + } + if (typeof settings === 'string') { + settings = getSettingsFromString(settings); + } + return 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 (canReflect.isPromise(result)) { + result.then(function (result) { + if (result !== undefined) { + response(200, result); + } + }); + } else { + 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.1.7#xhr*/ +define('can-fixture@3.1.7#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.1.7#fixture*/ +define('can-fixture@3.1.7#fixture', [ + 'require', + 'exports', + 'module', + './core', + './store', + './xhr', + 'can-reflect', + 'can-log/dev/dev', + 'can-namespace' +], function (require, exports, module) { + (function (global, 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 canDev = require('can-log/dev/dev'); + 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 = function () { + canDev.warn('You are using the global fixture. Make sure you import can-fixture.'); + return fixture.apply(this, arguments); + }; + } + module.exports = ns.fixture = fixture; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-fixture@3.1.7#test/store-test*/ +define('can-fixture@3.1.7#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'] })); + var done = assert.async(); + 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' + }] + }); + done(); + }); + }); + QUnit.test('anything with a schema will be converted to a queryLogic automatically', function (assert) { + var store = fixture.store([{ + _id: 0, + name: 'foo' + }], { identity: ['id'] }); + var res = store.get({ _id: 0 }); + assert.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 }); + assert.ok(res, 'an object works'); + }); + QUnit.test('createData, destroyData, updateData', function (assert) { + var store = fixture.store([{ + id: 0, + name: 'foo' + }], new QueryLogic({ identity: ['id'] })); + var done = assert.async(); + store.createData({ data: { name: 'bar' } }, function (instance) { + assert.deepEqual(instance, { + id: 1, + name: 'bar' + }); + done(); + }); + }); + QUnit.test('createData with a string id', function (assert) { + var store = fixture.store([{ + id: 'helloorld', + name: 'foo' + }], new QueryLogic({ identity: ['id'] })); + var done = assert.async(); + store.createData({ data: { name: 'bar' } }, function (instance) { + assert.deepEqual(instance, { + id: '1', + name: 'bar' + }); + done(); + }); + }); +}); +/*can-set-legacy@1.0.1#can-set-legacy*/ +define('can-set-legacy@1.0.1#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.1.7#test/fixture_test*/ +define('can-fixture@3.1.7#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', + 'can-define/map/map' +], function (require, exports, module) { + (function (global, __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 DefineMap = require('can-define/map/map'); + var errorCallback = function (xhr, status, error) { + assert.ok(false, error); + done(); + }; + 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 !== '/') { + QUnit.test('static fixtures', function (assert) { + var done = assert.async(); + 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) { + assert.equal(data.sweet, 'ness', 'can.get works'); + $.ajax({ + url: 'something', + method: 'POST', + dataType: 'json' + }).then(function (data) { + assert.equal(data.sweet, 'ness', 'can.post works'); + $.ajax({ + url: 'something', + method: 'PATCH', + dataType: 'json' + }).then(function (data) { + assert.equal(data.sweet, 'ness', 'can.patch works'); + done(); + }, errorCallback); + }, errorCallback); + }, errorCallback); + }); + } + if (__dirname !== '/') { + QUnit.test('static fixtures (using method signature)', function (assert) { + var done = assert.async(); + fixture({ + method: 'get', + url: 'method/{id}' + }, __dirname + '/fixtures/method.{id}.json'); + $.ajax({ + url: 'method/4', + dataType: 'json' + }).then(function (data) { + assert.equal(data.id, 4, 'Got data with proper id using method'); + done(); + }, errorCallback); + }); + } + if (__dirname !== '/') { + QUnit.test('static fixtures (using type signature)', function (assert) { + var done = assert.async(); + fixture({ + type: 'get', + url: 'type/{id}' + }, __dirname + '/fixtures/type.{id}.json'); + $.ajax({ + url: 'type/4', + dataType: 'json' + }).then(function (data) { + assert.equal(data.id, 4, 'Got data with proper id using type'); + done(); + }, errorCallback); + }); + } + if (__dirname !== '/') { + QUnit.test('templated static fixtures', function (assert) { + var done = assert.async(); + fixture('GET some/{id}', __dirname + '/fixtures/stuff.{id}.json'); + $.ajax({ + url: 'some/3', + dataType: 'json' + }).then(function (data) { + assert.equal(data.id, 3, 'Got data with proper id'); + done(); + }, errorCallback); + }); + } + QUnit.test('dynamic fixtures', function (assert) { + var done = assert.async(); + fixture.delay = 10; + fixture('something', function () { + return [{ sweet: 'ness' }]; + }); + $.ajax({ + url: 'something', + dataType: 'json' + }).done(function (data) { + assert.equal(data[0].sweet, 'ness', 'can.get works'); + done(); + }); + }); + QUnit.test('dynamic fixtures return promises', function (assert) { + var done = assert.async(); + fixture.delay = 10; + fixture('something', function () { + return Promise.resolve([{ sweet: 'ness' }]); + }); + $.ajax({ + url: 'something', + dataType: 'json' + }).then(function (data) { + assert.equal(data[0].sweet, 'ness', 'can.get works'); + done(); + }); + }); + if (__dirname !== '/') { + QUnit.test('fixture function', function (assert) { + assert.expect(3); + var done = assert.async(); + var url = __dirname + '/fixtures/foo.json'; + fixture(url, __dirname + '/fixtures/foobar.json'); + $.ajax({ + url: url, + dataType: 'json' + }).done(function (data) { + assert.equal(data.sweet, 'ner', 'url passed works'); + fixture(url, __dirname + '/fixtures/test.json'); + $.ajax({ + url: url, + dataType: 'json' + }).done(function (data) { + assert.equal(data.sweet, 'ness', 'replaced'); + fixture(url, null); + $.ajax({ + url: url, + dataType: 'json' + }).done(function (data) { + assert.equal(data.a, 'b', 'removed'); + done(); + }); + }); + }); + }); + } + QUnit.test('fixture.store fixtures', function (assert) { + var done = assert.async(); + 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) { + assert.equal(things.data[0].name, 'thing 29', 'first item is correct'); + assert.equal(things.data.length, 11, 'there are 11 items'); + done(); + } + }); + }); + QUnit.test('fixture.store fixtures should have unique IDs', function (assert) { + var done = assert.async(); + 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]; + assert.ok(seenIds.indexOf(thing.id) === -1); + seenIds.push(thing.id); + } + done(); + } + }); + }); + QUnit.test('fixture.store should assign unique IDs when fixtures provide IDs', function (assert) { + 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) { + assert.ok(false, 'ajax failure: ' + error); + done(); + }); + } + var request = $.ajax({ + url: '/models', + dataType: 'json', + type: 'post', + data: { name: 'My test object' } + }); + var done = assert.async(); + then(request, function (response) { + assert.notEqual(response.id, 0); + assert.notEqual(response.id, 1); + assert.notEqual(response.id, 2); + assert.equal(response.id, 3); + done(); + }); + }); + QUnit.test('simulating an error', function (assert) { + fixture('/foo', function (request, response) { + return response(401, { type: 'unauthorized' }); + }); + var done = assert.async(); + $.ajax({ + url: '/foo', + dataType: 'json' + }).done(function () { + assert.ok(false, 'success called'); + done(); + }).fail(function (original, type) { + assert.ok(true, 'error called'); + assert.deepEqual(JSON.parse(original.responseText), { type: 'unauthorized' }, 'Original text passed'); + done(); + }); + }); + QUnit.test('rand', function (assert) { + var rand = fixture.rand; + var num = rand(3); + assert.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++) { + assert.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++) { + assert.ok(matched[i], 'has ' + i); + delete matched[i]; + } + choices.forEach(function (choice) { + assert.ok(matched[choice], 'has ' + choice); + delete matched[choice]; + }); + assert.ok(canReflect.size(matched) === 0, 'nothing else unexpected'); + }); + QUnit.test('dataFromUrl', function (assert) { + var data = dataFromUrl('/thingers/{id}', '/thingers/5'); + assert.equal(data.id, 5, 'gets data'); + data = dataFromUrl('/thingers/5?hi.there', '/thingers/5?hi.there'); + assert.deepEqual(data, {}, 'gets data'); + }); + QUnit.test('core.dataFromUrl with double character value', function (assert) { + var data = dataFromUrl('/days/{id}/time_slots.json', '/days/17/time_slots.json'); + assert.equal(data.id, 17, 'gets data'); + }); + QUnit.test('fixture function gets id', function (assert) { + fixture('/thingers/{id}', function (settings) { + return { + id: settings.data.id, + name: 'justin' + }; + }); + var done = assert.async(); + $.ajax({ + url: '/thingers/5', + dataType: 'json', + data: { id: 5 } + }).done(function (data) { + assert.ok(data.id); + done(); + }); + }); + if (__dirname !== '/') { + QUnit.test('replacing and removing a fixture', function (assert) { + var url = __dirname + '/fixtures/remove.json'; + fixture('GET ' + url, function () { + return { weird: 'ness!' }; + }); + var done = assert.async(); + $.ajax({ + url: url, + dataType: 'json' + }).done(function (json) { + assert.equal(json.weird, 'ness!', 'fixture set right'); + fixture('GET ' + url, function () { + return { weird: 'ness?' }; + }); + $.ajax({ + url: url, + dataType: 'json' + }).done(function (json) { + assert.equal(json.weird, 'ness?', 'fixture set right'); + fixture('GET ' + url, null); + $.ajax({ + url: url, + dataType: 'json' + }).done(function (json) { + assert.equal(json.weird, 'ness', 'fixture set right'); + done(); + }); + }); + }); + }); + } + QUnit.test('fixture.store with can.Model', function (assert) { + 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); + var done = assert.async(); + function errorAndStart(e) { + assert.ok(false, 'borked' + e); + done(); + } + var check100Updated = function () { + return $.ajax({ + url: '/models/100', + dataType: 'json' + }).then(function (model) { + assert.equal(model.name, 'Updated test object', 'Successfully updated object'); + }); + }; + $.ajax({ + url: '/models', + dataType: 'json' + }).then(function (modelsData) { + var models = modelsData.data; + assert.equal(models.length, 100, 'Got 100 models for findAll with no parameters'); + assert.equal(models[95].name, 'Object 95', 'All models generated properly'); + return $.ajax({ + url: '/models/51', + dataType: 'json' + }).then(function (data) { + assert.equal(data.id, 51, 'Got correct object id'); + assert.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) { + assert.equal(newmodel.id, 100, 'Id got incremented'); + return $.ajax({ + url: '/models/100', + dataType: 'json' + }).then(function (model) { + assert.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) { + done(); + }, errorAndStart); + }, errorAndStart); + }, errorAndStart); + }, errorAndStart); + }, errorAndStart); + }, errorAndStart); + }, errorAndStart); + }); + QUnit.test('GET fixture.store returns 404 on findOne with bad id (#803)', function (assert) { + var store = fixture.store(2, function (i) { + return { + id: i, + name: 'Object ' + i + }; + }); + fixture('GET /models/{id}', store.getData); + var done = assert.async(); + $.ajax({ + url: '/models/3', + dataType: 'json' + }).then(function () { + }, function (data) { + assert.equal(data.status, 404, 'status'); + assert.equal(data.statusText, 'error', 'statusText'); + assert.equal(JSON.parse(data.responseText).title, 'no data', 'responseText'); + done(); + }); + }); + QUnit.test('fixture.store returns 404 on update with a bad id (#803)', function (assert) { + var store = fixture.store(5, function (i) { + return { + id: i, + name: 'Object ' + i + }; + }); + var done = assert.async(); + fixture('POST /models/{id}', store.updateData); + $.ajax({ + url: '/models/6', + dataType: 'json', + data: { 'jedan': 'dva' }, + type: 'POST' + }).then(function () { + assert.ok(false, 'success'); + done(); + }, function (data) { + assert.equal(data.status, 404, 'status'); + assert.equal(data.statusText, 'error', 'statusText'); + assert.equal(JSON.parse(data.responseText).title, 'no data', 'responseText'); + done(); + }); + }); + QUnit.test('fixture.store returns 404 on destroy with a bad id (#803)', function (assert) { + var store = fixture.store(2, function (i) { + return { + id: i, + name: 'Object ' + i + }; + }); + var done = assert.async(); + fixture('DELETE /models/{id}', store.destroyData); + $.ajax({ + url: '/models/6', + dataType: 'json', + type: 'DELETE' + }).then(function () { + }, function (data) { + assert.equal(data.status, 404, 'status'); + assert.equal(data.statusText, 'error', 'statusText'); + assert.equal(JSON.parse(data.responseText).title, 'no data', 'responseText'); + done(); + }); + }); + QUnit.test('fixture.store can use id of different type (#742)', function (assert) { + 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); + var done = assert.async(); + $.ajax({ + url: '/models', + dataType: 'json', + data: { filter: { parentId: '4' } } + }).then(function (models) { + assert.equal(models.data.length, 1, 'Got one model'); + assert.deepEqual(models.data[0], { + id: 2, + parentId: 4, + name: 'Object 2' + }); + done(); + }); + }); + QUnit.test('fixture("METHOD /path", store) should use the right method', function (assert) { + var store = fixture.store(100, function (i) { + return { + id: i, + name: 'Object ' + i + }; + }); + fixture('GET /models', store); + var done = assert.async(); + $.ajax({ + url: '/models', + dataType: 'json' + }).then(function (models) { + assert.equal(models.data.length, 100, 'Gotta catch up all!'); + done(); + }); + }); + QUnit.test('fixture with response callback', function (assert) { + assert.expect(4); + fixture.delay = 10; + fixture('responseCb', function (orig, response) { + response({ sweet: 'ness' }); + }); + fixture('responseErrorCb', function (orig, response) { + response(404, 'This is an error from callback'); + }); + var done = assert.async(); + $.ajax({ + url: 'responseCb', + dataType: 'json' + }).done(function (data) { + assert.equal(data.sweet, 'ness', 'can.get works'); + }); + $.ajax({ + url: 'responseErrorCb', + dataType: 'json' + }).fail(function (orig, error, text) { + assert.equal(error, 'error', 'Got error status'); + assert.equal(orig.responseText, 'This is an error from callback', 'Got error text'); + }); + fixture('cbWithTimeout', function (orig, response) { + setTimeout(function () { + response([{ epic: 'ness' }]); + }, 10); + }); + $.ajax({ + url: 'cbWithTimeout', + dataType: 'json' + }).done(function (data) { + assert.equal(data[0].epic, 'ness', 'Got responsen with timeout'); + done(); + }); + }); + QUnit.test('store create works with an empty array of items', function (assert) { + var store = fixture.store(0, function () { + return {}; + }); + var done = assert.async(); + store.createData({ data: {} }, function (responseData, responseHeaders) { + assert.equal(responseData.id, 1, 'the first id is 1'); + done(); + }); + }); + QUnit.test('store creates sequential ids', function (assert) { + var store = fixture.store(0, function () { + return {}; + }); + var done = assert.async(); + store.createData({ data: {} }, function (responseData, responseHeaders) { + assert.equal(responseData.id, 1, 'the first id is 1'); + createSecond(); + }); + function createSecond() { + store.createData({ data: {} }, function (responseData, responseHeaders) { + assert.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) { + assert.equal(responseData.id, 3, 'the third id is 3'); + done(); + }); + } + }); + QUnit.test('fixture updates request.data with id', function (assert) { + assert.expect(1); + var done = assert.async(); + fixture('foo/{id}', function (request) { + assert.equal(request.data.id, 5); + done(); + }); + $.ajax({ url: 'foo/5' }); + }); + QUnit.test('create a store with array and comparison object', function (assert) { + 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); + var done = assert.async(); + $.ajax({ + url: '/presetStore', + method: 'get', + data: { + filter: { + year: 2013, + modelId: 1 + } + }, + dataType: 'json' + }).then(function (response) { + assert.equal(response.data[0].id, 1, 'got the first item'); + assert.equal(response.data.length, 1, 'only got one item'); + done(); + }); + }); + 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'); + }); + }); + QUnit.test('store with objects allows .create, .update and .destroy (#1471)', function (assert) { + assert.expect(4); + 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' + }); + }; + var done = assert.async(); + findAll().then(function (carsData) { + assert.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) { + assert.equal(carsData.data.length, 7, 'One car less'); + assert.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) { + assert.equal(cars.data.length, 8, 'New car created'); + done(); + }); + }); + QUnit.test('filtering works', function (assert) { + var next; + var store = fixture.store([ + { + state: 'CA', + name: 'Casadina' + }, + { + state: 'NT', + name: 'Alberny' + } + ], new QueryLogic({ identity: ['state'] })); + fixture({ 'GET /api/cities': store.getListData }); + var done = assert.async(); + $.getJSON('/api/cities?filter[state]=CA').then(function (data) { + assert.deepEqual(data, { + data: [{ + state: 'CA', + name: 'Casadina' + }], + count: 1 + }); + done(); + }, function (e) { + assert.ok(false, '' + e); + done(); + }); + }); + QUnit.test('filtering works with nested props', function (assert) { + var done = assert.async(); + 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) { + assert.deepEqual(responseData, { + count: 1, + data: [{ + id: 2, + name: 'Crab Barn', + slug: 'crab-barn', + address: { + city: 'Alberny', + state: 'NT' + } + }] + }); + done(); + }, function (e) { + assert.ok(false); + done(); + }); + }); + QUnit.test('filtering works with nested.props', function (assert) { + var done = assert.async(); + 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) { + assert.deepEqual(responseData, { + count: 1, + data: [{ + id: 2, + name: 'Crab Barn', + slug: 'crab-barn', + address: { + city: 'Alberny', + state: 'NT' + } + }] + }); + done(); + }); + }); + QUnit.test('onreadystatechange, event is passed', function (assert) { + fixture('GET something', function () { + return {}; + }); + var xhr = new XMLHttpRequest(); + xhr.open('GET', 'something'); + xhr.onreadystatechange = function (ev) { + assert.ok(ev.target != null, 'the event object passed to onreadystatechange'); + done(); + }; + xhr.send(); + var done = assert.async(); + }); + if (__dirname !== '/') { + QUnit.test('doesn\'t break onreadystatechange (#3)', function (assert) { + var ready = assert.async(); + var url = __dirname + '/fixtures/test.json'; + var xhr = new XMLHttpRequest(); + xhr.onreadystatechange = function () { + if (xhr.readyState === 4) { + assert.ok(true, 'we made a successful request'); + ready(); + } + }; + xhr.open('GET', url); + xhr.send(); + }); + } + QUnit.module('XHR Shim'); + QUnit.test('Supports onload', function (assert) { + var xhr = new XMLHttpRequest(); + assert.ok('onload' in xhr, 'shim passes onload detection'); + }); + if (__dirname !== '/') { + QUnit.test('supports addEventListener on XHR shim', function (assert) { + var ready = assert.async(); + var url = __dirname + '/fixtures/test.json'; + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + assert.ok(true, 'our shim supports addEventListener'); + ready(); + }); + xhr.open('GET', url); + xhr.send(); + }); + } + if (__dirname !== '/') { + QUnit.test('supports removeEventListener on XHR shim', function (assert) { + var ready = assert.async(); + var url = __dirname + '/fixtures/test.json'; + var xhr = new XMLHttpRequest(); + var onload = function () { + assert.ok(false, 'this should not be called'); + }; + xhr.addEventListener('load', onload); + xhr.removeEventListener('load', onload); + xhr.onload = function () { + setTimeout(function () { + assert.ok(true, 'didn\'t call the event listener'); + ready(); + }); + }; + xhr.open('GET', url); + xhr.send(); + }); + } + QUnit.test('supports setDisableHeaderCheck', function (assert) { + var xhr = new XMLHttpRequest(); + try { + xhr.setDisableHeaderCheck(true); + assert.ok(true, 'did not throw'); + } catch (e) { + assert.ok(false, 'do not support setDisableHeaderCheck'); + } + }); + if (__dirname !== '/') { + QUnit.test('supports setRequestHeader', function (assert) { + var ready = assert.async(); + var url = __dirname + '/fixtures/test.json'; + var xhr = new XMLHttpRequest(); + xhr.setRequestHeader('foo', 'bar'); + xhr.onreadystatechange = function () { + if (xhr.readyState === 4) { + assert.equal(xhr._requestHeaders.foo, 'bar', 'header was set'); + ready(); + } + }; + xhr.open('GET', url); + xhr.send(); + }); + } + if (__dirname !== '/') { + QUnit.test('supports getResponseHeader', function (assert) { + var ready = assert.async(); + var url = __dirname + '/fixtures/test.json'; + var xhr = new XMLHttpRequest(); + xhr.onreadystatechange = function () { + if (xhr.readyState === 4) { + var header = xhr.getResponseHeader('Content-Type'); + assert.ok(header.indexOf('application/json') >= 0, 'got correct header back'); + ready(); + } + }; + xhr.open('GET', url); + xhr.send(); + }); + } + QUnit.test('supports getAllResponseHeaders', function (assert) { + var ready = assert.async(); + 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); + assert.ok(typeof headers === 'string', 'got headers back'); + assert.ok(parsed.foo === 'bar', 'got proper values'); + ready(); + } + }; + xhr.open('GET', 'something'); + xhr.send(); + }); + QUnit.test('pass data to response handler (#13)', function (assert) { + var ready = assert.async(); + fixture('GET something', function (req, res) { + res(403, { message: 'No bad guys' }); + }); + var xhr = new XMLHttpRequest(); + xhr.open('GET', 'something'); + xhr.onreadystatechange = function (ev) { + assert.deepEqual(JSON.parse(this.responseText), { message: 'No bad guys' }, 'correct response'); + assert.equal(this.status, 403, 'correct status'); + ready(); + }; + xhr.send(); + }); + QUnit.test('pass return value for fixture', function (assert) { + var ready = assert.async(); + fixture('GET something', { foo: 'bar' }); + var xhr = new XMLHttpRequest(); + xhr.open('GET', 'something'); + xhr.onreadystatechange = function (ev) { + assert.deepEqual(JSON.parse(this.responseText), { foo: 'bar' }, 'correct response'); + assert.equal(this.status, 200, 'correct status'); + ready(); + }; + xhr.send(); + }); + if (__dirname !== '/') { + QUnit.test('pass headers in fallthrough', function (assert) { + var ready = assert.async(); + var url = __dirname + '/fixtures/foobar.json'; + var xhr = new XMLHttpRequest(); + assert.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) { + assert.equal(key, 'foo'); + assert.equal(val, 'bar'); + }; + } + if (originalXhr.readyState === 4) { + ready(); + } + }; + xhr.send(); + }); + } + QUnit.test('first set.Algebra CRUD works (#12)', function (assert) { + assert.expect(5); + 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' + }); + }; + var done = assert.async(); + findAll().then(function (carsData) { + assert.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) { + assert.equal(carsData.data.length, 7, 'One car less'); + assert.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) { + assert.equal(cars.data.length, 8, 'New car created'); + return $.ajax({ + url: '/cars/5', + method: 'get', + dataType: 'json' + }); + }).then(function (car) { + assert.equal(car.name, '2013 Altima', 'get a single car works'); + done(); + }); + }); + QUnit.test('set.Algebra CRUD works (#12)', function (assert) { + assert.expect(5); + 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' + }); + }; + var done = assert.async(); + findAll().then(function (carsData) { + assert.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) { + assert.equal(carsData.data.length, 7, 'One car less'); + assert.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) { + assert.equal(cars.data.length, 8, 'New car created'); + return $.ajax({ + url: '/cars/5', + method: 'get', + dataType: 'json' + }); + }).then(function (car) { + assert.equal(car.name, '2013 Altima', 'get a single car works'); + done(); + }); + }); + QUnit.test('set.Algebra clauses work', function (assert) { + var ready = assert.async(); + 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) { + assert.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; + }); + assert.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; + }); + assert.deepEqual(names, [ + '2013 Focus', + '2013 Leaf' + ], 'pagination works'); + ready(); + }); + }); + QUnit.test('storeConnection reset', function (assert) { + 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) { + assert.equal(carsData.data.length, 2, 'Got all cars'); + done(); + }); + var done = assert.async(); + }); + function makeAlgebraTest(fixtureUrl) { + return function (assert) { + assert.expect(5); + 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' + }); + }; + var done = assert.async(); + findAll().then(function (carsData) { + assert.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) { + assert.equal(carsData.data.length, 7, 'One car less'); + assert.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) { + assert.equal(cars.data.length, 8, 'New car created'); + return $.ajax({ + url: '/cars/5', + method: 'get', + dataType: 'json' + }); + }).then(function (car) { + assert.equal(car.name, '2013 Altima', 'get a single car works'); + done(); + }); + }; + } + QUnit.test('set.Algebra CRUD works with easy hookup (#12)', makeAlgebraTest('/cars/{_id}')); + QUnit.test('set.Algebra CRUD works with easy hookup and list-style url (#52)', makeAlgebraTest('/cars')); + QUnit.test('store.getList and store.get', function (assert) { + 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); + assert.equal(store.getList({ year: 2013 }).data.length, 4, 'filtered'); + assert.deepEqual(store.get({ _id: 5 }).name, '2013 Altima', 'get'); + }); + QUnit.test('supports addEventListener on shim using fixture', function (assert) { + var ready = assert.async(); + fixture('/addEventListener', function () { + return {}; + }); + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + assert.ok(true, 'our shim supports addEventListener'); + ready(); + }); + xhr.open('GET', '/addEventListener'); + xhr.send(); + }); + if (__dirname !== '/') { + QUnit.test('supports sync on XHR shim (#23)', function (assert) { + var url = __dirname + '/fixtures/test.json'; + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + assert.ok(true, 'our shim supports addEventListener'); + }); + xhr.open('GET', url, false); + xhr.send(); + }); + } + QUnit.test('supports sync fixtures (#23)', function (assert) { + fixture('/sync', function () { + return {}; + }); + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + assert.ok(true, 'our shim supports sync'); + }); + xhr.open('GET', '/sync', false); + xhr.send(); + }); + if (__dirname !== '/') { + QUnit.test('supports sync redirect fixtures (#23)', function (assert) { + fixture('/sync_redirect', __dirname + '/fixtures/test.json'); + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + assert.ok(true, 'our shim supports sync redirect'); + }); + xhr.open('GET', '/sync_redirect', false); + xhr.send(); + }); + } + if (__dirname !== '/') { + QUnit.test('slow mode works (#26)', function (assert) { + var ready = assert.async(); + 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; + assert.ok(delay >= 900, delay + 'ms >= 900ms'); + fixture({ url: url }, null); + ready(); + }); + xhr.open('GET', url); + xhr.send(); + }); + } + QUnit.test('onload should be triggered for HTTP error responses (#36)', function (assert) { + var done = assert.async(); + fixture('/onload', function (req, res) { + res(400); + }); + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + assert.ok(true, 'onload should be invoked'); + fixture('/onload', null); + done(); + }); + xhr.addEventListener('error', function () { + assert.ok(false, 'onerror should not be invoked'); + fixture('/onload', null); + done(); + }); + xhr.open('GET', '/onload'); + xhr.send(); + }); + QUnit.test('responseText & responseXML should not be set for arraybuffer types (#38)', function (assert) { + var done = assert.async(); + fixture('/onload', '/test/fixtures/foo.json'); + var oldError = window.onerror; + window.onerror = function (msg, url, line) { + assert.ok(false, 'There should not be an error'); + done(); + }; + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + fixture('/onload', null); + window.onerror = oldError; + assert.ok(true, 'Got here without an error'); + done(); + }); + xhr.responseType = 'arraybuffer'; + xhr.open('GET', '/onload'); + xhr.send(); + }); + QUnit.test('fixture with timeout does not run if $.ajax timeout less than delay', function (assert) { + var done = assert.async(); + var delay = fixture.delay; + fixture.delay = 1000; + fixture('/onload', function () { + fixture('/onload', null); + assert.ok(false, 'timed out xhr did not abort'); + done(); + }); + $.ajax({ + url: '/onload', + timeout: 50, + error: function (xhr) { + fixture('/onload', null); + assert.ok(true, 'Got to the error handler'); + assert.equal(xhr.statusText, 'timeout'); + assert.equal(xhr.status, '0'); + done(); + } + }); + fixture.delay = delay; + }); + QUnit.test('response headers are set', function (assert) { + var ready = assert.async(); + fixture('GET /todos', function (request, response) { + response(200, '{}', { foo: 'bar' }); + }); + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + var headers = parseHeaders(xhr.getAllResponseHeaders()); + assert.ok(headers.foo === 'bar', 'header was set'); + ready(); + }); + xhr.open('GET', '/todos'); + xhr.send(); + }); + QUnit.test('match values in get data', function (assert) { + var ready = assert.async(); + fixture({ + method: 'GET', + url: '/data-value', + data: { name: 'justin' } + }, function (request, response) { + assert.ok(true, 'got it'); + return {}; + }); + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + ready(); + }); + xhr.open('GET', '/data-value?name=justin&age=22'); + xhr.send(); + }); + QUnit.test('universal match (#2000)', function (assert) { + var ready = assert.async(); + fixture({}, function () { + assert.ok(true, 'got hit'); + return {}; + }); + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + ready(); + fixture.fixtures.splice(0, fixture.fixtures.length); + }); + xhr.open('GET', '/something-totally-unexpected-62'); + xhr.send(); + }); + QUnit.test('set.Algebra stores provide a count (#58)', function (assert) { + 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); + var done = assert.async(); + $.ajax({ + url: '/cars', + dataType: 'json', + data: { + start: 2, + end: 3 + } + }).then(function (carsData) { + assert.equal(carsData.data.length, 2, 'Got 2 cars'); + assert.equal(carsData.count, 8, 'got the count'); + done(); + }, function () { + assert.ok(false, 'borked'); + done(); + }); + }); + QUnit.test('should allow Arrays as data type (#133)', function (assert) { + var ready = assert.async(); + fixture('/array-data', function (req, res) { + assert.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); + assert.ok(true, 'should not throw when sending Array'); + ready(); + }); + xhr.open('GET', '/array-data'); + xhr.send(data); + }); + QUnit.test('should allow FormData as data type (#133)', function (assert) { + var ready = assert.async(); + fixture('/upload', function (req, res) { + assert.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); + assert.ok(true, 'should not throw when sending FormData'); + ready(); + }); + xhr.open('POST', '/upload', true); + xhr.send(data); + }); + QUnit.test('fixture returns the old fixture callback when fixtures are removed (#34)', function (assert) { + var funcA = function () { + return 'foo'; + }; + fixture('/services/thing', funcA); + var oldFixtures = fixture('/services/thing', null); + assert.deepEqual(oldFixtures, [{ + fixture: funcA, + url: '/services/thing' + }]); + }); + QUnit.test('Using with nested types', function (assert) { + var done = assert.async(); + var Pet = DefineMap.extend('Pet', { name: 'string' }); + var Person = DefineMap.extend('Person', { + id: { + type: 'number', + identity: true + }, + name: 'string', + pet: Pet + }); + var store = fixture.store([{ + id: 1, + name: 'Dorothy', + pet: { name: 'Max' } + }], new QueryLogic(Person)); + fixture('/api/persons/{id}', store); + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + var data = JSON.parse(this.responseText); + var xhr2 = new XMLHttpRequest(); + xhr2.addEventListener('load', function () { + var data = JSON.parse(this.responseText); + assert.equal(data.pet.name, 'Max', 'Still have the Pet type'); + done(); + }); + xhr2.open('PUT', '/api/persons/1', true); + xhr2.send(data); + }); + xhr.open('GET', '/api/persons/1', true); + xhr.send(); + }); + if ('onabort' in XMLHttpRequest._XHR.prototype) { + QUnit.test('fixture with timeout aborts if xhr timeout less than delay', function (assert) { + var done = assert.async(); + 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); + assert.ok(true, 'Got to the error handler'); + assert.equal(xhr.statusText, ''); + assert.equal(xhr.status, 0); + done(); + }); + xhr.addEventListener('load', function () { + fixture('/onload', null); + assert.ok(false, 'timed out xhr did not abort'); + done(); + }); + }); + QUnit.test('dynamic fixture with timeout does not run if xhr timeout less than delay', function (assert) { + var done = assert.async(); + var delay = fixture.delay; + fixture.delay = 1000; + fixture('/onload', function () { + fixture('/onload', null); + assert.ok(false, 'timed out xhr did not abort'); + done(); + }); + var xhr = new XMLHttpRequest(); + xhr.open('GET', '/onload'); + setTimeout(function () { + xhr.abort(); + }, 50); + xhr.send(); + xhr.addEventListener('abort', function () { + fixture('/onload', null); + assert.ok(true, 'Got to the error handler'); + assert.equal(xhr.statusText, ''); + assert.equal(xhr.status, 0); + done(); + }); + fixture.delay = delay; + }); + QUnit.test('abort() sets readyState correctly', function (assert) { + var done = assert.async(); + fixture('/foo', function () { + return {}; + }); + var xhr = new XMLHttpRequest(); + xhr.open('GET', '/foo'); + xhr.addEventListener('abort', function () { + fixture('/foo', null); + assert.ok(true, 'Got to the error handler'); + assert.equal(xhr.status, 0); + assert.equal(xhr.statusText, ''); + setTimeout(function () { + assert.equal(xhr.readyState, 0); + done(); + }, 50); + }); + xhr.send(); + xhr.abort(); + }); + QUnit.test('abort() of already completed fixture', function (assert) { + var done = assert.async(); + fixture('/foo', function () { + return {}; + }); + var xhr = new XMLHttpRequest(); + xhr.open('GET', '/foo'); + xhr.addEventListener('load', function () { + fixture('/foo', null); + assert.equal(xhr.readyState, 4); + xhr.abort(); + done(); + }); + xhr.send(); + }); + QUnit.test('should be able to call getResponseHeader onload', function (assert) { + var ready = assert.async(); + fixture('/onload', function (req, res) { + res(400); + }); + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + fixture('/onload', null); + xhr.getResponseHeader('Set-Cookie'); + assert.ok(true, 'should not throw when calling getResponseHeader'); + ready(); + }); + xhr.open('GET', '/onload'); + xhr.send(); + }); + testHelpers.dev.devOnlyTest('window.fixture warns when called', function (assert) { + var teardown = testHelpers.dev.willWarn(/You are using the global fixture\. Make sure you import can-fixture\./, function (message, matched) { + if (matched) { + assert.ok(true, 'received warning'); + } + }); + window.fixture('GET /api/products', function () { + return {}; + }); + teardown(); + }); + testHelpers.dev.devOnlyTest('Works with steal-clone', function (assert) { + 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); + assert.ok(true, 'Got to the load event without throwing'); + done(); + }); + xhr.open('GET', '/onload'); + xhr.send(); + }); + }); + var done = assert.async(); + }); + } + }(function () { + return this; + }(), '/', require, exports, module)); +}); +/*can-fixture-socket@2.0.3#src/store*/ +define('can-fixture-socket@2.0.3#src/store', [ + 'require', + 'exports', + 'module', + 'can-fixture/core' +], function (require, exports, module) { + 'use strict'; + 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.3#src/feathers-client*/ +define('can-fixture-socket@2.0.3#src/feathers-client', [ + 'require', + 'exports', + 'module', + './store', + 'can-assign' +], function (require, exports, module) { + 'use strict'; + 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.3#src/index*/ +define('can-fixture-socket@2.0.3#src/index', [ + 'require', + 'exports', + 'module', + './feathers-client' +], function (require, exports, module) { + 'use strict'; + 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, dataArgs); + if (dataArgs && typeof dataArgs[0] === 'string' && pubsub[dataArgs[0] + '::' + event]) { + event = dataArgs.shift() + '::' + 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.3#can-fixture-socket*/ +define('can-fixture-socket@2.0.3#can-fixture-socket', [ + 'require', + 'exports', + 'module', + './src/index', + './src/store' +], function (require, exports, module) { + 'use strict'; + 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@2.1.2#index*/ +define('ms@2.1.2#index', function (require, exports, module) { + var s = 1000; + var m = s * 60; + var h = m * 60; + var d = h * 24; + var w = d * 7; + 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' && isFinite(val)) { + 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 > 100) { + return; + } + var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|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 'weeks': + case 'week': + case 'w': + return n * w; + 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) { + var msAbs = Math.abs(ms); + if (msAbs >= d) { + return Math.round(ms / d) + 'd'; + } + if (msAbs >= h) { + return Math.round(ms / h) + 'h'; + } + if (msAbs >= m) { + return Math.round(ms / m) + 'm'; + } + if (msAbs >= s) { + return Math.round(ms / s) + 's'; + } + return ms + 'ms'; + } + function fmtLong(ms) { + var msAbs = Math.abs(ms); + if (msAbs >= d) { + return plural(ms, msAbs, d, 'day'); + } + if (msAbs >= h) { + return plural(ms, msAbs, h, 'hour'); + } + if (msAbs >= m) { + return plural(ms, msAbs, m, 'minute'); + } + if (msAbs >= s) { + return plural(ms, msAbs, s, 'second'); + } + return ms + ' ms'; + } + function plural(ms, msAbs, n, name) { + var isPlural = msAbs >= n * 1.5; + return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : ''); + } +}); +/*debug@4.1.1#src/common*/ +define('debug@4.1.1#src/common', [ + 'require', + 'exports', + 'module', + 'ms' +], function (require, exports, module) { + function setup(env) { + createDebug.debug = createDebug; + createDebug.default = createDebug; + createDebug.coerce = coerce; + createDebug.disable = disable; + createDebug.enable = enable; + createDebug.enabled = enabled; + createDebug.humanize = require('ms'); + Object.keys(env).forEach(key => { + createDebug[key] = env[key]; + }); + createDebug.instances = []; + createDebug.names = []; + createDebug.skips = []; + createDebug.formatters = {}; + function selectColor(namespace) { + let hash = 0; + for (let i = 0; i < namespace.length; i++) { + hash = (hash << 5) - hash + namespace.charCodeAt(i); + hash |= 0; + } + return createDebug.colors[Math.abs(hash) % createDebug.colors.length]; + } + createDebug.selectColor = selectColor; + function createDebug(namespace) { + let prevTime; + function debug(...args) { + if (!debug.enabled) { + return; + } + const self = debug; + const curr = Number(new Date()); + const ms = curr - (prevTime || curr); + self.diff = ms; + self.prev = prevTime; + self.curr = curr; + prevTime = curr; + args[0] = createDebug.coerce(args[0]); + if (typeof args[0] !== 'string') { + args.unshift('%O'); + } + let index = 0; + args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => { + if (match === '%%') { + return match; + } + index++; + const formatter = createDebug.formatters[format]; + if (typeof formatter === 'function') { + const val = args[index]; + match = formatter.call(self, val); + args.splice(index, 1); + index--; + } + return match; + }); + createDebug.formatArgs.call(self, args); + const logFn = self.log || createDebug.log; + logFn.apply(self, args); + } + debug.namespace = namespace; + debug.enabled = createDebug.enabled(namespace); + debug.useColors = createDebug.useColors(); + debug.color = selectColor(namespace); + debug.destroy = destroy; + debug.extend = extend; + if (typeof createDebug.init === 'function') { + createDebug.init(debug); + } + createDebug.instances.push(debug); + return debug; + } + function destroy() { + const index = createDebug.instances.indexOf(this); + if (index !== -1) { + createDebug.instances.splice(index, 1); + return true; + } + return false; + } + function extend(namespace, delimiter) { + const newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace); + newDebug.log = this.log; + return newDebug; + } + function enable(namespaces) { + createDebug.save(namespaces); + createDebug.names = []; + createDebug.skips = []; + let i; + const split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/); + const len = split.length; + for (i = 0; i < len; i++) { + if (!split[i]) { + continue; + } + namespaces = split[i].replace(/\*/g, '.*?'); + if (namespaces[0] === '-') { + createDebug.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); + } else { + createDebug.names.push(new RegExp('^' + namespaces + '$')); + } + } + for (i = 0; i < createDebug.instances.length; i++) { + const instance = createDebug.instances[i]; + instance.enabled = createDebug.enabled(instance.namespace); + } + } + function disable() { + const namespaces = [ + ...createDebug.names.map(toNamespace), + ...createDebug.skips.map(toNamespace).map(namespace => '-' + namespace) + ].join(','); + createDebug.enable(''); + return namespaces; + } + function enabled(name) { + if (name[name.length - 1] === '*') { + return true; + } + let i; + let len; + for (i = 0, len = createDebug.skips.length; i < len; i++) { + if (createDebug.skips[i].test(name)) { + return false; + } + } + for (i = 0, len = createDebug.names.length; i < len; i++) { + if (createDebug.names[i].test(name)) { + return true; + } + } + return false; + } + function toNamespace(regexp) { + return regexp.toString().substring(2, regexp.toString().length - 2).replace(/\.\*\?$/, '*'); + } + function coerce(val) { + if (val instanceof Error) { + return val.stack || val.message; + } + return val; + } + createDebug.enable(createDebug.load()); + return createDebug; + } + module.exports = setup; +}); +/*debug@4.1.1#src/browser*/ +define('debug@4.1.1#src/browser', [ + 'require', + 'exports', + 'module', + './common' +], function (require, exports, module) { + (function (global, require, exports, module) { + exports.log = log; + exports.formatArgs = formatArgs; + exports.save = save; + exports.load = load; + exports.useColors = useColors; + exports.storage = localstorage(); + exports.colors = [ + '#0000CC', + '#0000FF', + '#0033CC', + '#0033FF', + '#0066CC', + '#0066FF', + '#0099CC', + '#0099FF', + '#00CC00', + '#00CC33', + '#00CC66', + '#00CC99', + '#00CCCC', + '#00CCFF', + '#3300CC', + '#3300FF', + '#3333CC', + '#3333FF', + '#3366CC', + '#3366FF', + '#3399CC', + '#3399FF', + '#33CC00', + '#33CC33', + '#33CC66', + '#33CC99', + '#33CCCC', + '#33CCFF', + '#6600CC', + '#6600FF', + '#6633CC', + '#6633FF', + '#66CC00', + '#66CC33', + '#9900CC', + '#9900FF', + '#9933CC', + '#9933FF', + '#99CC00', + '#99CC33', + '#CC0000', + '#CC0033', + '#CC0066', + '#CC0099', + '#CC00CC', + '#CC00FF', + '#CC3300', + '#CC3333', + '#CC3366', + '#CC3399', + '#CC33CC', + '#CC33FF', + '#CC6600', + '#CC6633', + '#CC9900', + '#CC9933', + '#CCCC00', + '#CCCC33', + '#FF0000', + '#FF0033', + '#FF0066', + '#FF0099', + '#FF00CC', + '#FF00FF', + '#FF3300', + '#FF3333', + '#FF3366', + '#FF3399', + '#FF33CC', + '#FF33FF', + '#FF6600', + '#FF6633', + '#FF9900', + '#FF9933', + '#FFCC00', + '#FFCC33' + ]; + function useColors() { + if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) { + return true; + } + if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) { + return false; + } + return typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || typeof window !== 'undefined' && window.console && (window.console.firebug || window.console.exception && window.console.table) || typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31 || typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/); + } + function formatArgs(args) { + args[0] = (this.useColors ? '%c' : '') + this.namespace + (this.useColors ? ' %c' : ' ') + args[0] + (this.useColors ? '%c ' : ' ') + '+' + module.exports.humanize(this.diff); + if (!this.useColors) { + return; + } + const c = 'color: ' + this.color; + args.splice(1, 0, c, 'color: inherit'); + let index = 0; + let lastC = 0; + args[0].replace(/%[a-zA-Z%]/g, match => { + if (match === '%%') { + return; + } + index++; + if (match === '%c') { + lastC = index; + } + }); + args.splice(lastC, 0, c); + } + function log(...args) { + return typeof console === 'object' && console.log && console.log(...args); + } + function save(namespaces) { + try { + if (namespaces) { + exports.storage.setItem('debug', namespaces); + } else { + exports.storage.removeItem('debug'); + } + } catch (error) { + } + } + function load() { + let r; + try { + r = exports.storage.getItem('debug'); + } catch (error) { + } + if (!r && typeof process !== 'undefined' && 'env' in process) { + r = process.env.DEBUG; + } + return r; + } + function localstorage() { + try { + return localStorage; + } catch (error) { + } + } + module.exports = require('./common')(exports); + const {formatters} = module.exports; + formatters.j = function (v) { + try { + return JSON.stringify(v); + } catch (error) { + return '[UnexpectedJSONParseError]: ' + error.message; + } + }; + }(function () { + return this; + }(), require, exports, module)); +}); +/*socket.io-client@2.3.0#lib/url*/ +define('socket.io-client@2.3.0#lib/url', [ + 'require', + 'exports', + 'module', + 'parseuri', + 'debug' +], function (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 || typeof location !== 'undefined' && 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; + } +}); +/*ms@2.0.0#index*/ +define('ms@2.0.0#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 > 100) { + 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@3.1.0#src/debug*/ +define('debug@3.1.0#src/debug', [ + 'require', + 'exports', + 'module', + 'ms' +], function (require, exports, module) { + exports = module.exports = createDebug.debug = createDebug['default'] = createDebug; + exports.coerce = coerce; + exports.disable = disable; + exports.enable = enable; + exports.enabled = enabled; + exports.humanize = require('ms'); + exports.instances = []; + exports.names = []; + exports.skips = []; + exports.formatters = {}; + function selectColor(namespace) { + var hash = 0, i; + for (i in namespace) { + hash = (hash << 5) - hash + namespace.charCodeAt(i); + hash |= 0; + } + return exports.colors[Math.abs(hash) % exports.colors.length]; + } + function createDebug(namespace) { + var prevTime; + function debug() { + if (!debug.enabled) + return; + var self = debug; + var curr = +new Date(); + var ms = curr - (prevTime || curr); + self.diff = ms; + self.prev = prevTime; + self.curr = curr; + prevTime = curr; + 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.unshift('%O'); + } + var index = 0; + args[0] = args[0].replace(/%([a-zA-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; + }); + exports.formatArgs.call(self, args); + var logFn = debug.log || exports.log || console.log.bind(console); + logFn.apply(self, args); + } + debug.namespace = namespace; + debug.enabled = exports.enabled(namespace); + debug.useColors = exports.useColors(); + debug.color = selectColor(namespace); + debug.destroy = destroy; + if ('function' === typeof exports.init) { + exports.init(debug); + } + exports.instances.push(debug); + return debug; + } + function destroy() { + var index = exports.instances.indexOf(this); + if (index !== -1) { + exports.instances.splice(index, 1); + return true; + } else { + return false; + } + } + function enable(namespaces) { + exports.save(namespaces); + exports.names = []; + exports.skips = []; + var i; + var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/); + var len = split.length; + for (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 + '$')); + } + } + for (i = 0; i < exports.instances.length; i++) { + var instance = exports.instances[i]; + instance.enabled = exports.enabled(instance.namespace); + } + } + function disable() { + exports.enable(''); + } + function enabled(name) { + if (name[name.length - 1] === '*') { + return true; + } + 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@3.1.0#src/browser*/ +define('debug@3.1.0#src/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 = [ + '#0000CC', + '#0000FF', + '#0033CC', + '#0033FF', + '#0066CC', + '#0066FF', + '#0099CC', + '#0099FF', + '#00CC00', + '#00CC33', + '#00CC66', + '#00CC99', + '#00CCCC', + '#00CCFF', + '#3300CC', + '#3300FF', + '#3333CC', + '#3333FF', + '#3366CC', + '#3366FF', + '#3399CC', + '#3399FF', + '#33CC00', + '#33CC33', + '#33CC66', + '#33CC99', + '#33CCCC', + '#33CCFF', + '#6600CC', + '#6600FF', + '#6633CC', + '#6633FF', + '#66CC00', + '#66CC33', + '#9900CC', + '#9900FF', + '#9933CC', + '#9933FF', + '#99CC00', + '#99CC33', + '#CC0000', + '#CC0033', + '#CC0066', + '#CC0099', + '#CC00CC', + '#CC00FF', + '#CC3300', + '#CC3333', + '#CC3366', + '#CC3399', + '#CC33CC', + '#CC33FF', + '#CC6600', + '#CC6633', + '#CC9900', + '#CC9933', + '#CCCC00', + '#CCCC33', + '#FF0000', + '#FF0033', + '#FF0066', + '#FF0099', + '#FF00CC', + '#FF00FF', + '#FF3300', + '#FF3333', + '#FF3366', + '#FF3399', + '#FF33CC', + '#FF33FF', + '#FF6600', + '#FF6633', + '#FF9900', + '#FF9933', + '#FFCC00', + '#FFCC33' + ]; + function useColors() { + if (typeof window !== 'undefined' && window.process && window.process.type === 'renderer') { + return true; + } + if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) { + return false; + } + return typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || typeof window !== 'undefined' && window.console && (window.console.firebug || window.console.exception && window.console.table) || typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31 || typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/); + } + exports.formatters.j = function (v) { + try { + return JSON.stringify(v); + } catch (err) { + return '[UnexpectedJSONParseError]: ' + err.message; + } + }; + function formatArgs(args) { + var useColors = this.useColors; + args[0] = (useColors ? '%c' : '') + this.namespace + (useColors ? ' %c' : ' ') + args[0] + (useColors ? '%c ' : ' ') + '+' + exports.humanize(this.diff); + if (!useColors) + return; + var c = 'color: ' + this.color; + args.splice(1, 0, c, 'color: inherit'); + var index = 0; + var lastC = 0; + args[0].replace(/%[a-zA-Z%]/g, function (match) { + if ('%%' === match) + return; + index++; + if ('%c' === match) { + lastC = index; + } + }); + args.splice(lastC, 0, c); + } + 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) { + } + if (!r && typeof process !== 'undefined' && 'env' in process) { + r = process.env.DEBUG; + } + return r; + } + exports.enable(load()); + function localstorage() { + try { + return window.localStorage; + } catch (e) { + } + } +}); +/*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; + }; +}); +/*isarray@2.0.1#index*/ +define('isarray@2.0.1#index', function (require, exports, module) { + var toString = {}.toString; + module.exports = Array.isArray || function (arr) { + return toString.call(arr) == '[object Array]'; + }; +}); +/*socket.io-parser@3.3.0#is-buffer*/ +define('socket.io-parser@3.3.0#is-buffer', function (require, exports, module) { + module.exports = isBuf; + var withNativeBuffer = typeof Buffer === 'function' && typeof Buffer.isBuffer === 'function'; + var withNativeArrayBuffer = typeof ArrayBuffer === 'function'; + var isView = function (obj) { + return typeof ArrayBuffer.isView === 'function' ? ArrayBuffer.isView(obj) : obj.buffer instanceof ArrayBuffer; + }; + function isBuf(obj) { + return withNativeBuffer && Buffer.isBuffer(obj) || withNativeArrayBuffer && (obj instanceof ArrayBuffer || isView(obj)); + } +}); +/*socket.io-parser@3.3.0#binary*/ +define('socket.io-parser@3.3.0#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'); + var toString = Object.prototype.toString; + var withNativeBlob = typeof Blob === 'function' || typeof Blob !== 'undefined' && toString.call(Blob) === '[object BlobConstructor]'; + var withNativeFile = typeof File === 'function' || typeof File !== 'undefined' && toString.call(File) === '[object FileConstructor]'; + exports.deconstructPacket = function (packet) { + var buffers = []; + var packetData = packet.data; + var pack = packet; + pack.data = _deconstructPacket(packetData, buffers); + pack.attachments = buffers.length; + return { + packet: pack, + buffers: buffers + }; + }; + function _deconstructPacket(data, buffers) { + 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], buffers); + } + return newData; + } else if (typeof data === 'object' && !(data instanceof Date)) { + var newData = {}; + for (var key in data) { + newData[key] = _deconstructPacket(data[key], buffers); + } + return newData; + } + return data; + } + exports.reconstructPacket = function (packet, buffers) { + packet.data = _reconstructPacket(packet.data, buffers); + packet.attachments = undefined; + return packet; + }; + function _reconstructPacket(data, buffers) { + if (!data) + return data; + if (data && data._placeholder) { + return buffers[data.num]; + } else if (isArray(data)) { + for (var i = 0; i < data.length; i++) { + data[i] = _reconstructPacket(data[i], buffers); + } + } else if (typeof data === 'object') { + for (var key in data) { + data[key] = _reconstructPacket(data[key], buffers); + } + } + return data; + } + exports.removeBlobs = function (data, callback) { + function _removeBlobs(obj, curKey, containingObject) { + if (!obj) + return obj; + if (withNativeBlob && obj instanceof Blob || withNativeFile && 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 (typeof obj === 'object' && !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@3.3.0#index*/ +define('socket.io-parser@3.3.0#index', [ + 'require', + 'exports', + 'module', + 'debug', + 'component-emitter', + './binary', + 'isarray', + './is-buffer' +], function (require, exports, module) { + var debug = require('debug')('socket.io-parser'); + var Emitter = require('component-emitter'); + var binary = require('./binary'); + var isArray = require('isarray'); + 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() { + } + var ERROR_PACKET = exports.ERROR + '"encode error"'; + 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 = '' + obj.type; + if (exports.BINARY_EVENT === obj.type || exports.BINARY_ACK === obj.type) { + str += obj.attachments + '-'; + } + if (obj.nsp && '/' !== obj.nsp) { + str += obj.nsp + ','; + } + if (null != obj.id) { + str += obj.id; + } + if (null != obj.data) { + var payload = tryStringify(obj.data); + if (payload !== false) { + str += payload; + } else { + return ERROR_PACKET; + } + } + debug('encoded %j as %s', obj, str); + return str; + } + function tryStringify(str) { + try { + return JSON.stringify(str); + } catch (e) { + return false; + } + } + 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 (typeof obj === 'string') { + 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 i = 0; + var p = { type: Number(str.charAt(0)) }; + if (null == exports.types[p.type]) { + return error('unknown packet type ' + p.type); + } + 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)) { + var payload = tryParse(str.substr(i)); + var isPayloadValid = payload !== false && (p.type === exports.ERROR || isArray(payload)); + if (isPayloadValid) { + p.data = payload; + } else { + return error('invalid payload'); + } + } + debug('decoded %s as %j', str, p); + return p; + } + function tryParse(str) { + try { + return JSON.parse(str); + } catch (e) { + return false; + } + } + 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(msg) { + return { + type: exports.ERROR, + data: 'parser error: ' + msg + }; + } +}); +/*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@3.4.1#lib/globalThis.browser*/ +define('engine.io-client@3.4.1#lib/globalThis.browser', function (require, exports, module) { + module.exports = function () { + if (typeof self !== 'undefined') { + return self; + } else if (typeof window !== 'undefined') { + return window; + } else { + return Function('return this')(); + } + }(); +}); +/*engine.io-client@3.4.1#lib/xmlhttprequest*/ +define('engine.io-client@3.4.1#lib/xmlhttprequest', [ + 'require', + 'exports', + 'module', + 'has-cors', + './globalThis' +], function (require, exports, module) { + (function (global, require, exports, module) { + var hasCORS = require('has-cors'); + var globalThis = require('./globalThis'); + 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 globalThis[(['Active'].concat('Object').join('X'))]('Microsoft.XMLHTTP'); + } catch (e) { + } + } + }; + }(function () { + return this; + }(), require, exports, module)); +}); +/*engine.io-parser@2.2.0#lib/keys*/ +define('engine.io-parser@2.2.0#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-binary2@1.0.3#index*/ +define('has-binary2@1.0.3#index', [ + 'require', + 'exports', + 'module', + 'isarray' +], function (require, exports, module) { + (function (global, require, exports, module) { + var isArray = require('isarray'); + var toString = Object.prototype.toString; + var withNativeBlob = typeof Blob === 'function' || typeof Blob !== 'undefined' && toString.call(Blob) === '[object BlobConstructor]'; + var withNativeFile = typeof File === 'function' || typeof File !== 'undefined' && toString.call(File) === '[object FileConstructor]'; + module.exports = hasBinary; + function hasBinary(obj) { + if (!obj || typeof obj !== 'object') { + return false; + } + if (isArray(obj)) { + for (var i = 0, l = obj.length; i < l; i++) { + if (hasBinary(obj[i])) { + return true; + } + } + return false; + } + if (typeof Buffer === 'function' && Buffer.isBuffer && Buffer.isBuffer(obj) || typeof ArrayBuffer === 'function' && obj instanceof ArrayBuffer || withNativeBlob && obj instanceof Blob || withNativeFile && obj instanceof File) { + return true; + } + if (obj.toJSON && typeof obj.toJSON === 'function' && arguments.length === 1) { + return hasBinary(obj.toJSON(), true); + } + for (var key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key) && hasBinary(obj[key])) { + return true; + } + } + return false; + } + }(function () { + return this; + }(), require, exports, module)); +}); +/*arraybuffer.slice@0.0.7#index*/ +define('arraybuffer.slice@0.0.7#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() { + } +}); +/*engine.io-parser@2.2.0#lib/utf8*/ +define('engine.io-parser@2.2.0#lib/utf8', function (require, exports, module) { + 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 checkScalarValue(codePoint, strict) { + if (codePoint >= 55296 && codePoint <= 57343) { + if (strict) { + throw Error('Lone surrogate U+' + codePoint.toString(16).toUpperCase() + ' is not a scalar value'); + } + return false; + } + return true; + } + function createByte(codePoint, shift) { + return stringFromCharCode(codePoint >> shift & 63 | 128); + } + function encodeCodePoint(codePoint, strict) { + if ((codePoint & 4294967168) == 0) { + return stringFromCharCode(codePoint); + } + var symbol = ''; + if ((codePoint & 4294965248) == 0) { + symbol = stringFromCharCode(codePoint >> 6 & 31 | 192); + } else if ((codePoint & 4294901760) == 0) { + if (!checkScalarValue(codePoint, strict)) { + codePoint = 65533; + } + 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 utf8encode(string, opts) { + opts = opts || {}; + var strict = false !== opts.strict; + var codePoints = ucs2decode(string); + var length = codePoints.length; + var index = -1; + var codePoint; + var byteString = ''; + while (++index < length) { + codePoint = codePoints[index]; + byteString += encodeCodePoint(codePoint, strict); + } + 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(strict) { + 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) { + 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 checkScalarValue(codePoint, strict) ? codePoint : 65533; + } else { + throw Error('Invalid continuation byte'); + } + } + if ((byte1 & 248) == 240) { + byte2 = readContinuationByte(); + byte3 = readContinuationByte(); + byte4 = readContinuationByte(); + codePoint = (byte1 & 7) << 18 | byte2 << 12 | byte3 << 6 | byte4; + if (codePoint >= 65536 && codePoint <= 1114111) { + return codePoint; + } + } + throw Error('Invalid UTF-8 detected'); + } + var byteArray; + var byteCount; + var byteIndex; + function utf8decode(byteString, opts) { + opts = opts || {}; + var strict = false !== opts.strict; + byteArray = ucs2decode(byteString); + byteCount = byteArray.length; + byteIndex = 0; + var codePoints = []; + var tmp; + while ((tmp = decodeSymbol(strict)) !== false) { + codePoints.push(tmp); + } + return ucs2encode(codePoints); + } + module.exports = { + version: '2.1.2', + encode: utf8encode, + decode: utf8decode + }; +}); +/*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.5#index*/ +define('blob@0.0.5#index', function (require, exports, module) { + var BlobBuilder = typeof BlobBuilder !== 'undefined' ? BlobBuilder : typeof WebKitBlobBuilder !== 'undefined' ? WebKitBlobBuilder : typeof MSBlobBuilder !== 'undefined' ? MSBlobBuilder : typeof MozBlobBuilder !== 'undefined' ? MozBlobBuilder : false; + 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) { + return ary.map(function (chunk) { + 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; + } + return buf; + } + return chunk; + }); + } + function BlobBuilderConstructor(ary, options) { + options = options || {}; + var bb = new BlobBuilder(); + mapArrayBufferViews(ary).forEach(function (part) { + bb.append(part); + }); + return options.type ? bb.getBlob(options.type) : bb.getBlob(); + } + ; + function BlobConstructor(ary, options) { + return new Blob(mapArrayBufferViews(ary), options || {}); + } + ; + if (typeof Blob !== 'undefined') { + BlobBuilderConstructor.prototype = Blob.prototype; + BlobConstructor.prototype = Blob.prototype; + } + module.exports = function () { + if (blobSupported) { + return blobSupportsArrayBufferView ? Blob : BlobConstructor; + } else if (blobBuilderSupported) { + return BlobBuilderConstructor; + } else { + return undefined; + } + }(); +}); +/*engine.io-parser@2.2.0#lib/browser*/ +define('engine.io-parser@2.2.0#lib/browser', [ + 'require', + 'exports', + 'module', + './keys', + 'has-binary2', + 'arraybuffer.slice', + 'after', + './utf8', + 'base64-arraybuffer', + 'blob' +], function (require, exports, module) { + var keys = require('./keys'); + var hasBinary = require('has-binary2'); + var sliceBuffer = require('arraybuffer.slice'); + var after = require('after'); + var utf8 = require('./utf8'); + var base64encoder; + if (typeof ArrayBuffer !== 'undefined') { + 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 (typeof supportsBinary === 'function') { + callback = supportsBinary; + supportsBinary = false; + } + if (typeof utf8encode === 'function') { + callback = utf8encode; + utf8encode = null; + } + var data = packet.data === undefined ? undefined : packet.data.buffer || packet.data; + if (typeof ArrayBuffer !== 'undefined' && data instanceof ArrayBuffer) { + return encodeArrayBuffer(packet, supportsBinary, callback); + } else if (typeof Blob !== 'undefined' && data instanceof 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), { strict: false }) : 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 () { + exports.encodePacket({ + type: packet.type, + data: fr.result + }, 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 (typeof Blob !== 'undefined' && packet.data instanceof 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 += 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, { strict: false }); + } 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, false, 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; + continue; + } + 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, false); + 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 = []; + 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) { + return callback(err, 0, 1); + } + msgLength += tailArray[i]; + } + 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); + }); + }; +}); +/*engine.io-client@3.4.1#lib/transport*/ +define('engine.io-client@3.4.1#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.withCredentials = opts.withCredentials; + 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.isReactNative = opts.isReactNative; + 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@3.4.1#lib/transports/polling*/ +define('engine.io-client@3.4.1#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@3.4.1#lib/transports/polling-xhr*/ +define('engine.io-client@3.4.1#lib/transports/polling-xhr', [ + 'require', + 'exports', + 'module', + 'xmlhttprequest-ssl', + './polling', + 'component-emitter', + 'component-inherit', + 'debug', + '../globalThis' +], 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'); + var globalThis = require('../globalThis'); + module.exports = XHR; + module.exports.Request = Request; + function empty() { + } + function XHR(opts) { + Polling.call(this, opts); + this.requestTimeout = opts.requestTimeout; + this.extraHeaders = opts.extraHeaders; + if (typeof location !== 'undefined') { + var isSSL = 'https:' === location.protocol; + var port = location.port; + if (!port) { + port = isSSL ? 443 : 80; + } + this.xd = typeof location !== 'undefined' && opts.hostname !== location.hostname || port !== opts.port; + this.xs = opts.secure !== isSSL; + } + } + 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.withCredentials = this.withCredentials; + 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.withCredentials = opts.withCredentials; + 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 && xhr.setDisableHeaderCheck(true); + for (var i in this.extraHeaders) { + if (this.extraHeaders.hasOwnProperty(i)) { + xhr.setRequestHeader(i, this.extraHeaders[i]); + } + } + } + } catch (e) { + } + 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 = this.withCredentials; + } + 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 (xhr.readyState === 2) { + try { + var contentType = xhr.getResponseHeader('Content-Type'); + if (self.supportsBinary && contentType === 'application/octet-stream' || contentType === 'application/octet-stream; charset=UTF-8') { + xhr.responseType = 'arraybuffer'; + } + } catch (e) { + } + } + if (4 !== xhr.readyState) + return; + if (200 === xhr.status || 1223 === xhr.status) { + self.onLoad(); + } else { + setTimeout(function () { + self.onError(typeof xhr.status === 'number' ? xhr.status : 0); + }, 0); + } + }; + } + debug('xhr data %s', this.data); + xhr.send(this.data); + } catch (e) { + setTimeout(function () { + self.onError(e); + }, 0); + return; + } + if (typeof document !== 'undefined') { + 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 (typeof document !== 'undefined') { + delete Request.requests[this.index]; + } + this.xhr = null; + }; + Request.prototype.onLoad = function () { + var data; + try { + var contentType; + try { + contentType = this.xhr.getResponseHeader('Content-Type'); + } catch (e) { + } + if (contentType === 'application/octet-stream' || contentType === 'application/octet-stream; charset=UTF-8') { + data = this.xhr.response || this.xhr.responseText; + } else { + data = this.xhr.responseText; + } + } catch (e) { + this.onError(e); + } + if (null != data) { + this.onData(data); + } + }; + Request.prototype.hasXDR = function () { + return typeof XDomainRequest !== 'undefined' && !this.xs && this.enablesXDR; + }; + Request.prototype.abort = function () { + this.cleanup(); + }; + Request.requestsCount = 0; + Request.requests = {}; + if (typeof document !== 'undefined') { + if (typeof attachEvent === 'function') { + attachEvent('onunload', unloadHandler); + } else if (typeof addEventListener === 'function') { + var terminationEvent = 'onpagehide' in globalThis ? 'pagehide' : 'unload'; + addEventListener(terminationEvent, 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@3.4.1#lib/transports/polling-jsonp*/ +define('engine.io-client@3.4.1#lib/transports/polling-jsonp', [ + 'require', + 'exports', + 'module', + './polling', + 'component-inherit', + '../globalThis' +], function (require, exports, module) { + (function (global, require, exports, module) { + var Polling = require('./polling'); + var inherit = require('component-inherit'); + var globalThis = require('../globalThis'); + 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) { + callbacks = globalThis.___eio = globalThis.___eio || []; + } + this.index = callbacks.length; + var self = this; + callbacks.push(function (msg) { + self.onData(msg); + }); + this.query.j = this.index; + if (typeof addEventListener === 'function') { + 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 = '